Mercurial > hg > nginx-quic
annotate src/mail/ngx_mail_parse.c @ 8711:be08b858086a quic
HTTP/3: http3_hq directive and NGX_HTTP_V3_HQ macro.
Listen quic parameter is no longer supported.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Sat, 04 Dec 2021 10:52:55 +0300 |
parents | b38728495e1a |
children |
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, | |
8459
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
diff
changeset
|
24 sw_command, |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
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: | |
8459
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
diff
changeset
|
40 s->cmd_start = p; |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
diff
changeset
|
41 state = sw_command; |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
diff
changeset
|
42 |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
diff
changeset
|
43 /* fall through */ |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
diff
changeset
|
44 |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
diff
changeset
|
45 case sw_command: |
1136 | 46 if (ch == ' ' || ch == CR || ch == LF) { |
8459
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
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 | |
8459
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
diff
changeset
|
96 s->cmd.data = s->cmd_start; |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
diff
changeset
|
97 s->cmd.len = p - s->cmd_start; |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
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 | |
8459
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
diff
changeset
|
118 case sw_invalid: |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
diff
changeset
|
119 goto invalid; |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
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 | |
8459
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
diff
changeset
|
209 s->state = sw_invalid; |
1136 | 210 |
8459
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
diff
changeset
|
211 /* skip invalid command till LF */ |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
diff
changeset
|
212 |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
diff
changeset
|
213 for ( /* void */ ; p < s->buffer->last; p++) { |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
diff
changeset
|
214 if (*p == LF) { |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
diff
changeset
|
215 s->state = sw_start; |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
diff
changeset
|
216 s->buffer->pos = p + 1; |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
diff
changeset
|
217 return NGX_MAIL_PARSE_INVALID_COMMAND; |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
diff
changeset
|
218 } |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
diff
changeset
|
219 } |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
diff
changeset
|
220 |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
diff
changeset
|
221 s->buffer->pos = p; |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
diff
changeset
|
222 |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8458
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 { |
8462
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8461
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, |
8464
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
234 sw_tag, |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
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: |
8464
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
258 s->tag_start = p; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
259 state = sw_tag; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
260 |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
261 /* fall through */ |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
262 |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
263 case sw_tag: |
527 | 264 switch (ch) { |
265 case ' ': | |
8464
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
266 s->tag.len = p - s->tag_start + 1; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
267 s->tag.data = s->tag_start; |
527 | 268 state = sw_spaces_before_command; |
269 break; | |
270 case CR: | |
271 case LF: | |
8464
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
272 goto invalid; |
8463
4b15f1b92100
Mail: stricter checking of IMAP tags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8462
diff
changeset
|
273 default: |
4b15f1b92100
Mail: stricter checking of IMAP tags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8462
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:
8462
diff
changeset
|
275 && (ch < '0' || ch > '9') && ch != '-' && ch != '.' |
4b15f1b92100
Mail: stricter checking of IMAP tags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8462
diff
changeset
|
276 && ch != '_') |
4b15f1b92100
Mail: stricter checking of IMAP tags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8462
diff
changeset
|
277 { |
4b15f1b92100
Mail: stricter checking of IMAP tags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8462
diff
changeset
|
278 goto invalid; |
4b15f1b92100
Mail: stricter checking of IMAP tags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8462
diff
changeset
|
279 } |
8464
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
280 if (p - s->tag_start > 31) { |
8463
4b15f1b92100
Mail: stricter checking of IMAP tags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8462
diff
changeset
|
281 goto invalid; |
4b15f1b92100
Mail: stricter checking of IMAP tags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8462
diff
changeset
|
282 } |
4b15f1b92100
Mail: stricter checking of IMAP tags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8462
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 |
8464
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
287 case sw_invalid: |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
288 goto invalid; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
289 |
527 | 290 case sw_spaces_before_command: |
291 switch (ch) { | |
292 case ' ': | |
293 break; | |
294 case CR: | |
295 case LF: | |
8464
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
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 |
8464
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
416 s->cmd.data = s->cmd_start; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
417 s->cmd.len = p - s->cmd_start; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
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; | |
8462
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8461
diff
changeset
|
492 |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8461
diff
changeset
|
493 if (s->backslash) { |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8461
diff
changeset
|
494 dst = s->arg_start; |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8461
diff
changeset
|
495 end = p; |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8461
diff
changeset
|
496 |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8461
diff
changeset
|
497 for (src = dst; src < end; dst++) { |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8461
diff
changeset
|
498 *dst = *src; |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8461
diff
changeset
|
499 if (*src++ == '\\') { |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8461
diff
changeset
|
500 *dst = *src++; |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8461
diff
changeset
|
501 } |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8461
diff
changeset
|
502 } |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8461
diff
changeset
|
503 |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8461
diff
changeset
|
504 arg->len = dst - s->arg_start; |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8461
diff
changeset
|
505 s->backslash = 0; |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8461
diff
changeset
|
506 } |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8461
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 | |
8464
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
642 s->state = sw_invalid; |
527 | 643 s->quoted = 0; |
8460
3974f4e56a4e
Mail: fixed s->arg_start clearing on invalid IMAP commands.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8459
diff
changeset
|
644 s->backslash = 0; |
543 | 645 s->no_sync_literal = 0; |
527 | 646 s->literal_len = 0; |
647 | |
8464
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
648 /* skip invalid command till LF */ |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
649 |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
650 for ( /* void */ ; p < s->buffer->last; p++) { |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
651 if (*p == LF) { |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
652 s->state = sw_start; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
653 s->buffer->pos = p + 1; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
654 |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
655 /* detect non-synchronizing literals */ |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
656 |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
657 if ((size_t) (p - s->buffer->start) > sizeof("{1+}") - 1) { |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
658 p--; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
659 |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
660 if (*p == CR) { |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
661 p--; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
662 } |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
663 |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
664 if (*p == '}' && *(p - 1) == '+') { |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
665 s->quit = 1; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
666 } |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
667 } |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
668 |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
669 return NGX_MAIL_PARSE_INVALID_COMMAND; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
670 } |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
671 } |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
672 |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
673 s->buffer->pos = p; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
diff
changeset
|
674 |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8463
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 |
8458
ba8a8299b904
Mail: optimized discarding invalid SMTP commands.
Maxim Dounin <mdounin@mdounin.ru>
parents:
8457
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; |
8457
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 |
8457
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 } |