Mercurial > hg > nginx
annotate src/mail/ngx_mail_parse.c @ 9300:5be23505292b default tip
SSI: fixed incorrect or duplicate stub output.
Following 3518:eb3aaf8bd2a9 (0.8.37), r->request_output is only set
if there are data in the first buffer sent in the subrequest. As a
result, following the change mentioned this flag cannot be used to
prevent duplicate ngx_http_ssi_stub_output() calls, since it is not
set if there was already some output, but the first buffer was empty.
Still, when there are multiple subrequests, even an empty subrequest
response might be delayed by the postpone filter, leading to a second
call of ngx_http_ssi_stub_output() during finalization from
ngx_http_writer() the subreqest buffers are released by the postpone
filter. Since r->request_output is not set after the first call, this
resulted in duplicate stub output.
Additionally, checking only the first buffer might be wrong in some
unusual cases. For example, the first buffer might be empty if
$r->flush() is called before printing any data in the embedded Perl
module.
Depending on the postpone_output value and corresponding sizes, this
issue can result in either duplicate or unexpected stub output, or
"zero size buf in writer" alerts.
Following 8124:f5515e727656 (1.23.4), it became slightly easier to
reproduce the issue, as empty static files and empty cache items now
result in a response with an empty buffer. Before the change, an empty
proxied response can be used to reproduce the issue.
Fix is check all buffers and set r->request_output if any non-empty
buffers are sent. This ensures that all unusual cases of non-empty
responses are covered, and also that r->request_output will be set
after the first stub output, preventing duplicate output.
Reported by Jan Gassen.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 04 Jul 2024 17:41:28 +0300 |
parents | 4538c1ffb0f8 |
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, | |
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 | |
9289
20017bff0de8
Mail: added some parsing debug logging.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9287
diff
changeset
|
33 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, |
20017bff0de8
Mail: added some parsing debug logging.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9287
diff
changeset
|
34 "pop3 parse: %d", state); |
20017bff0de8
Mail: added some parsing debug logging.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9287
diff
changeset
|
35 |
1136 | 36 for (p = s->buffer->pos; p < s->buffer->last; p++) { |
37 ch = *p; | |
38 | |
39 switch (state) { | |
40 | |
41 /* POP3 command */ | |
42 case sw_start: | |
7838
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7837
diff
changeset
|
43 s->cmd_start = p; |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7837
diff
changeset
|
44 state = sw_command; |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7837
diff
changeset
|
45 |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7837
diff
changeset
|
46 /* fall through */ |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7837
diff
changeset
|
47 |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7837
diff
changeset
|
48 case sw_command: |
1136 | 49 if (ch == ' ' || ch == CR || ch == LF) { |
7838
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7837
diff
changeset
|
50 c = s->cmd_start; |
1136 | 51 |
52 if (p - c == 4) { | |
53 | |
54 c0 = ngx_toupper(c[0]); | |
55 c1 = ngx_toupper(c[1]); | |
56 c2 = ngx_toupper(c[2]); | |
57 c3 = ngx_toupper(c[3]); | |
58 | |
59 if (c0 == 'U' && c1 == 'S' && c2 == 'E' && c3 == 'R') | |
60 { | |
61 s->command = NGX_POP3_USER; | |
62 | |
63 } else if (c0 == 'P' && c1 == 'A' && c2 == 'S' && c3 == 'S') | |
64 { | |
65 s->command = NGX_POP3_PASS; | |
66 | |
67 } else if (c0 == 'A' && c1 == 'P' && c2 == 'O' && c3 == 'P') | |
68 { | |
69 s->command = NGX_POP3_APOP; | |
70 | |
71 } else if (c0 == 'Q' && c1 == 'U' && c2 == 'I' && c3 == 'T') | |
72 { | |
73 s->command = NGX_POP3_QUIT; | |
74 | |
75 } else if (c0 == 'C' && c1 == 'A' && c2 == 'P' && c3 == 'A') | |
76 { | |
77 s->command = NGX_POP3_CAPA; | |
78 | |
79 } else if (c0 == 'A' && c1 == 'U' && c2 == 'T' && c3 == 'H') | |
80 { | |
81 s->command = NGX_POP3_AUTH; | |
82 | |
83 } else if (c0 == 'N' && c1 == 'O' && c2 == 'O' && c3 == 'P') | |
84 { | |
85 s->command = NGX_POP3_NOOP; | |
86 #if (NGX_MAIL_SSL) | |
87 } else if (c0 == 'S' && c1 == 'T' && c2 == 'L' && c3 == 'S') | |
88 { | |
89 s->command = NGX_POP3_STLS; | |
90 #endif | |
91 } else { | |
92 goto invalid; | |
93 } | |
94 | |
95 } else { | |
96 goto invalid; | |
97 } | |
98 | |
7838
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7837
diff
changeset
|
99 s->cmd.data = s->cmd_start; |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7837
diff
changeset
|
100 s->cmd.len = p - s->cmd_start; |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7837
diff
changeset
|
101 |
1136 | 102 switch (ch) { |
103 case ' ': | |
104 state = sw_spaces_before_argument; | |
105 break; | |
106 case CR: | |
107 state = sw_almost_done; | |
108 break; | |
109 case LF: | |
110 goto done; | |
111 } | |
112 break; | |
113 } | |
114 | |
115 if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) { | |
116 goto invalid; | |
117 } | |
118 | |
119 break; | |
120 | |
7838
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7837
diff
changeset
|
121 case sw_invalid: |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7837
diff
changeset
|
122 goto invalid; |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7837
diff
changeset
|
123 |
1136 | 124 case sw_spaces_before_argument: |
125 switch (ch) { | |
126 case ' ': | |
127 break; | |
128 case CR: | |
129 state = sw_almost_done; | |
130 break; | |
131 case LF: | |
132 goto done; | |
133 default: | |
134 if (s->args.nelts <= 2) { | |
135 state = sw_argument; | |
136 s->arg_start = p; | |
137 break; | |
138 } | |
139 goto invalid; | |
140 } | |
141 break; | |
142 | |
143 case sw_argument: | |
144 switch (ch) { | |
145 | |
146 case ' ': | |
147 | |
148 /* | |
149 * the space should be considered as part of the at username | |
150 * or password, but not of argument in other commands | |
151 */ | |
152 | |
153 if (s->command == NGX_POP3_USER | |
154 || s->command == NGX_POP3_PASS) | |
155 { | |
156 break; | |
157 } | |
158 | |
159 /* fall through */ | |
160 | |
161 case CR: | |
162 case LF: | |
163 arg = ngx_array_push(&s->args); | |
164 if (arg == NULL) { | |
165 return NGX_ERROR; | |
166 } | |
167 arg->len = p - s->arg_start; | |
168 arg->data = s->arg_start; | |
169 s->arg_start = NULL; | |
170 | |
171 switch (ch) { | |
172 case ' ': | |
173 state = sw_spaces_before_argument; | |
174 break; | |
175 case CR: | |
176 state = sw_almost_done; | |
177 break; | |
178 case LF: | |
179 goto done; | |
180 } | |
181 break; | |
182 | |
183 default: | |
184 break; | |
185 } | |
186 break; | |
187 | |
188 case sw_almost_done: | |
189 switch (ch) { | |
190 case LF: | |
191 goto done; | |
192 default: | |
193 goto invalid; | |
194 } | |
195 } | |
196 } | |
197 | |
198 s->buffer->pos = p; | |
199 s->state = state; | |
200 | |
201 return NGX_AGAIN; | |
202 | |
203 done: | |
204 | |
205 s->buffer->pos = p + 1; | |
206 s->state = (s->command != NGX_POP3_AUTH) ? sw_start : sw_argument; | |
207 | |
208 return NGX_OK; | |
209 | |
210 invalid: | |
211 | |
7838
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7837
diff
changeset
|
212 s->state = sw_invalid; |
1136 | 213 |
7838
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7837
diff
changeset
|
214 /* skip invalid command till LF */ |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7837
diff
changeset
|
215 |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7837
diff
changeset
|
216 for ( /* void */ ; p < s->buffer->last; p++) { |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7837
diff
changeset
|
217 if (*p == LF) { |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7837
diff
changeset
|
218 s->state = sw_start; |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7837
diff
changeset
|
219 s->buffer->pos = p + 1; |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7837
diff
changeset
|
220 return NGX_MAIL_PARSE_INVALID_COMMAND; |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7837
diff
changeset
|
221 } |
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 |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7837
diff
changeset
|
224 s->buffer->pos = p; |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7837
diff
changeset
|
225 |
815c63581be4
Mail: POP3 pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7837
diff
changeset
|
226 return NGX_AGAIN; |
1136 | 227 } |
228 | |
229 | |
1477 | 230 ngx_int_t |
231 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
|
232 { |
7841
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
233 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
|
234 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
|
235 enum { |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
236 sw_start = 0, |
7843
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
237 sw_tag, |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
238 sw_invalid, |
527 | 239 sw_spaces_before_command, |
240 sw_command, | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
241 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
|
242 sw_argument, |
543 | 243 sw_backslash, |
527 | 244 sw_literal, |
543 | 245 sw_no_sync_literal_argument, |
527 | 246 sw_start_literal_argument, |
247 sw_literal_argument, | |
248 sw_end_literal_argument, | |
249 sw_almost_done | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
250 } state; |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
251 |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
252 state = s->state; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
253 |
9289
20017bff0de8
Mail: added some parsing debug logging.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9287
diff
changeset
|
254 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, |
20017bff0de8
Mail: added some parsing debug logging.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9287
diff
changeset
|
255 "imap parse: %d", state); |
20017bff0de8
Mail: added some parsing debug logging.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9287
diff
changeset
|
256 |
527 | 257 for (p = s->buffer->pos; p < s->buffer->last; p++) { |
258 ch = *p; | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
259 |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
260 switch (state) { |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
261 |
527 | 262 /* IMAP tag */ |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
263 case sw_start: |
7843
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
264 s->tag_start = p; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
265 state = sw_tag; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
266 |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
267 /* fall through */ |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
268 |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
269 case sw_tag: |
527 | 270 switch (ch) { |
271 case ' ': | |
7843
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
272 s->tag.len = p - s->tag_start + 1; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
273 s->tag.data = s->tag_start; |
527 | 274 state = sw_spaces_before_command; |
275 break; | |
276 case CR: | |
277 case LF: | |
7843
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
278 goto invalid; |
7842
4b15f1b92100
Mail: stricter checking of IMAP tags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7841
diff
changeset
|
279 default: |
4b15f1b92100
Mail: stricter checking of IMAP tags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7841
diff
changeset
|
280 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
|
281 && (ch < '0' || ch > '9') && ch != '-' && ch != '.' |
4b15f1b92100
Mail: stricter checking of IMAP tags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7841
diff
changeset
|
282 && ch != '_') |
4b15f1b92100
Mail: stricter checking of IMAP tags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7841
diff
changeset
|
283 { |
4b15f1b92100
Mail: stricter checking of IMAP tags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7841
diff
changeset
|
284 goto invalid; |
4b15f1b92100
Mail: stricter checking of IMAP tags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7841
diff
changeset
|
285 } |
7843
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
286 if (p - s->tag_start > 31) { |
7842
4b15f1b92100
Mail: stricter checking of IMAP tags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7841
diff
changeset
|
287 goto invalid; |
4b15f1b92100
Mail: stricter checking of IMAP tags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7841
diff
changeset
|
288 } |
4b15f1b92100
Mail: stricter checking of IMAP tags.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7841
diff
changeset
|
289 break; |
527 | 290 } |
291 break; | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
292 |
7843
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
293 case sw_invalid: |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
294 goto invalid; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
295 |
527 | 296 case sw_spaces_before_command: |
297 switch (ch) { | |
298 case ' ': | |
299 break; | |
300 case CR: | |
301 case LF: | |
7843
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
302 goto invalid; |
527 | 303 default: |
304 s->cmd_start = p; | |
305 state = sw_command; | |
306 break; | |
307 } | |
308 break; | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
309 |
527 | 310 case sw_command: |
311 if (ch == ' ' || ch == CR || ch == LF) { | |
312 | |
313 c = s->cmd_start; | |
314 | |
315 switch (p - c) { | |
316 | |
317 case 4: | |
318 if ((c[0] == 'N' || c[0] == 'n') | |
319 && (c[1] == 'O'|| c[1] == 'o') | |
320 && (c[2] == 'O'|| c[2] == 'o') | |
321 && (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
|
322 { |
527 | 323 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
|
324 |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
325 } else { |
527 | 326 goto invalid; |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
327 } |
527 | 328 break; |
329 | |
330 case 5: | |
331 if ((c[0] == 'L'|| c[0] == 'l') | |
332 && (c[1] == 'O'|| c[1] == 'o') | |
333 && (c[2] == 'G'|| c[2] == 'g') | |
334 && (c[3] == 'I'|| c[3] == 'i') | |
335 && (c[4] == 'N'|| c[4] == 'n')) | |
336 { | |
337 s->command = NGX_IMAP_LOGIN; | |
338 | |
339 } else { | |
340 goto invalid; | |
341 } | |
342 break; | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
343 |
527 | 344 case 6: |
345 if ((c[0] == 'L'|| c[0] == 'l') | |
346 && (c[1] == 'O'|| c[1] == 'o') | |
347 && (c[2] == 'G'|| c[2] == 'g') | |
348 && (c[3] == 'O'|| c[3] == 'o') | |
349 && (c[4] == 'U'|| c[4] == 'u') | |
350 && (c[5] == 'T'|| c[5] == 't')) | |
351 { | |
352 s->command = NGX_IMAP_LOGOUT; | |
353 | |
354 } else { | |
355 goto invalid; | |
356 } | |
357 break; | |
358 | |
1136 | 359 #if (NGX_MAIL_SSL) |
583 | 360 case 8: |
361 if ((c[0] == 'S'|| c[0] == 's') | |
362 && (c[1] == 'T'|| c[1] == 't') | |
363 && (c[2] == 'A'|| c[2] == 'a') | |
364 && (c[3] == 'R'|| c[3] == 'r') | |
365 && (c[4] == 'T'|| c[4] == 't') | |
366 && (c[5] == 'T'|| c[5] == 't') | |
367 && (c[6] == 'L'|| c[6] == 'l') | |
368 && (c[7] == 'S'|| c[7] == 's')) | |
369 { | |
370 s->command = NGX_IMAP_STARTTLS; | |
371 | |
372 } else { | |
373 goto invalid; | |
374 } | |
375 break; | |
376 #endif | |
377 | |
527 | 378 case 10: |
379 if ((c[0] == 'C'|| c[0] == 'c') | |
380 && (c[1] == 'A'|| c[1] == 'a') | |
381 && (c[2] == 'P'|| c[2] == 'p') | |
382 && (c[3] == 'A'|| c[3] == 'a') | |
383 && (c[4] == 'B'|| c[4] == 'b') | |
384 && (c[5] == 'I'|| c[5] == 'i') | |
385 && (c[6] == 'L'|| c[6] == 'l') | |
386 && (c[7] == 'I'|| c[7] == 'i') | |
387 && (c[8] == 'T'|| c[8] == 't') | |
388 && (c[9] == 'Y'|| c[9] == 'y')) | |
389 { | |
390 s->command = NGX_IMAP_CAPABILITY; | |
391 | |
392 } else { | |
393 goto invalid; | |
394 } | |
395 break; | |
396 | |
1323 | 397 case 12: |
398 if ((c[0] == 'A'|| c[0] == 'a') | |
399 && (c[1] == 'U'|| c[1] == 'u') | |
400 && (c[2] == 'T'|| c[2] == 't') | |
401 && (c[3] == 'H'|| c[3] == 'h') | |
402 && (c[4] == 'E'|| c[4] == 'e') | |
403 && (c[5] == 'N'|| c[5] == 'n') | |
404 && (c[6] == 'T'|| c[6] == 't') | |
405 && (c[7] == 'I'|| c[7] == 'i') | |
406 && (c[8] == 'C'|| c[8] == 'c') | |
407 && (c[9] == 'A'|| c[9] == 'a') | |
408 && (c[10] == 'T'|| c[10] == 't') | |
409 && (c[11] == 'E'|| c[11] == 'e')) | |
410 { | |
411 s->command = NGX_IMAP_AUTHENTICATE; | |
412 | |
413 } else { | |
414 goto invalid; | |
415 } | |
416 break; | |
417 | |
527 | 418 default: |
419 goto invalid; | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
420 } |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
421 |
7843
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
422 s->cmd.data = s->cmd_start; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
423 s->cmd.len = p - s->cmd_start; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
424 |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
425 switch (ch) { |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
426 case ' ': |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
427 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
|
428 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
429 case CR: |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
430 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
|
431 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
432 case LF: |
527 | 433 goto done; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
434 } |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
435 break; |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
436 } |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
437 |
527 | 438 if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) { |
439 goto invalid; | |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
440 } |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
441 |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
442 break; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
443 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
444 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
|
445 switch (ch) { |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
446 case ' ': |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
447 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
448 case CR: |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
449 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
|
450 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
451 case LF: |
527 | 452 goto done; |
453 case '"': | |
454 if (s->args.nelts <= 2) { | |
455 s->quoted = 1; | |
456 s->arg_start = p + 1; | |
457 state = sw_argument; | |
458 break; | |
459 } | |
460 goto invalid; | |
461 case '{': | |
462 if (s->args.nelts <= 2) { | |
463 state = sw_literal; | |
464 break; | |
465 } | |
466 goto invalid; | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
467 default: |
527 | 468 if (s->args.nelts <= 2) { |
469 s->arg_start = p; | |
470 state = sw_argument; | |
471 break; | |
472 } | |
473 goto invalid; | |
474 } | |
475 break; | |
476 | |
477 case sw_argument: | |
1405
fdd064faf26a
escape " ", "%", and %00-%1F in login and password
Igor Sysoev <igor@sysoev.ru>
parents:
1323
diff
changeset
|
478 if (ch == ' ' && s->quoted) { |
fdd064faf26a
escape " ", "%", and %00-%1F in login and password
Igor Sysoev <igor@sysoev.ru>
parents:
1323
diff
changeset
|
479 break; |
fdd064faf26a
escape " ", "%", and %00-%1F in login and password
Igor Sysoev <igor@sysoev.ru>
parents:
1323
diff
changeset
|
480 } |
fdd064faf26a
escape " ", "%", and %00-%1F in login and password
Igor Sysoev <igor@sysoev.ru>
parents:
1323
diff
changeset
|
481 |
527 | 482 switch (ch) { |
483 case '"': | |
484 if (!s->quoted) { | |
485 break; | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
486 } |
527 | 487 s->quoted = 0; |
488 /* fall through */ | |
489 case ' ': | |
490 case CR: | |
491 case LF: | |
492 arg = ngx_array_push(&s->args); | |
493 if (arg == NULL) { | |
494 return NGX_ERROR; | |
495 } | |
496 arg->len = p - s->arg_start; | |
497 arg->data = s->arg_start; | |
7841
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
498 |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
499 if (s->backslash) { |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
500 dst = s->arg_start; |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
501 end = p; |
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 for (src = dst; src < end; dst++) { |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
504 *dst = *src; |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
505 if (*src++ == '\\') { |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
506 *dst = *src++; |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
507 } |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
508 } |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
509 |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
510 arg->len = dst - s->arg_start; |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
511 s->backslash = 0; |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
512 } |
ccdf83bee8c1
Mail: fixed backslash handling in IMAP literals.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7840
diff
changeset
|
513 |
527 | 514 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
|
515 |
527 | 516 switch (ch) { |
517 case '"': | |
518 case ' ': | |
519 state = sw_spaces_before_argument; | |
520 break; | |
521 case CR: | |
522 state = sw_almost_done; | |
523 break; | |
524 case LF: | |
525 goto done; | |
526 } | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
527 break; |
543 | 528 case '\\': |
529 if (s->quoted) { | |
530 s->backslash = 1; | |
531 state = sw_backslash; | |
532 } | |
533 break; | |
534 } | |
535 break; | |
536 | |
537 case sw_backslash: | |
538 switch (ch) { | |
539 case CR: | |
540 case LF: | |
541 goto invalid; | |
542 default: | |
543 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
|
544 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
545 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
546 |
527 | 547 case sw_literal: |
548 if (ch >= '0' && ch <= '9') { | |
549 s->literal_len = s->literal_len * 10 + (ch - '0'); | |
550 break; | |
551 } | |
552 if (ch == '}') { | |
553 state = sw_start_literal_argument; | |
554 break; | |
555 } | |
543 | 556 if (ch == '+') { |
557 state = sw_no_sync_literal_argument; | |
558 break; | |
559 } | |
560 goto invalid; | |
561 | |
562 case sw_no_sync_literal_argument: | |
563 if (ch == '}') { | |
564 s->no_sync_literal = 1; | |
565 state = sw_start_literal_argument; | |
566 break; | |
567 } | |
527 | 568 goto invalid; |
569 | |
570 case sw_start_literal_argument: | |
571 switch (ch) { | |
572 case CR: | |
573 break; | |
574 case LF: | |
575 s->buffer->pos = p + 1; | |
576 s->arg_start = p + 1; | |
543 | 577 if (s->no_sync_literal == 0) { |
578 s->state = sw_literal_argument; | |
579 return NGX_IMAP_NEXT; | |
580 } | |
581 state = sw_literal_argument; | |
582 s->no_sync_literal = 0; | |
583 break; | |
584 default: | |
585 goto invalid; | |
527 | 586 } |
543 | 587 break; |
527 | 588 |
589 case sw_literal_argument: | |
529 | 590 if (s->literal_len && --s->literal_len) { |
527 | 591 break; |
592 } | |
593 | |
594 arg = ngx_array_push(&s->args); | |
595 if (arg == NULL) { | |
596 return NGX_ERROR; | |
597 } | |
598 arg->len = p + 1 - s->arg_start; | |
599 arg->data = s->arg_start; | |
600 s->arg_start = NULL; | |
601 state = sw_end_literal_argument; | |
602 | |
603 break; | |
604 | |
605 case sw_end_literal_argument: | |
606 switch (ch) { | |
607 case '{': | |
608 if (s->args.nelts <= 2) { | |
609 state = sw_literal; | |
610 break; | |
611 } | |
612 goto invalid; | |
613 case CR: | |
614 state = sw_almost_done; | |
615 break; | |
616 case LF: | |
617 goto done; | |
618 default: | |
529 | 619 state = sw_spaces_before_argument; |
620 break; | |
527 | 621 } |
622 break; | |
623 | |
624 case sw_almost_done: | |
625 switch (ch) { | |
626 case LF: | |
627 goto done; | |
628 default: | |
629 goto invalid; | |
630 } | |
631 } | |
632 } | |
633 | |
634 s->buffer->pos = p; | |
635 s->state = state; | |
636 | |
637 return NGX_AGAIN; | |
638 | |
639 done: | |
640 | |
641 s->buffer->pos = p + 1; | |
1323 | 642 s->state = (s->command != NGX_IMAP_AUTHENTICATE) ? sw_start : sw_argument; |
527 | 643 |
644 return NGX_OK; | |
645 | |
646 invalid: | |
647 | |
7843
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
648 s->state = sw_invalid; |
527 | 649 s->quoted = 0; |
7839
3974f4e56a4e
Mail: fixed s->arg_start clearing on invalid IMAP commands.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7838
diff
changeset
|
650 s->backslash = 0; |
543 | 651 s->no_sync_literal = 0; |
527 | 652 s->literal_len = 0; |
653 | |
7843
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
654 /* skip invalid command till LF */ |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
655 |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
656 for ( /* void */ ; p < s->buffer->last; p++) { |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
657 if (*p == LF) { |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
658 s->state = sw_start; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
659 s->buffer->pos = p + 1; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
660 |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
661 /* detect non-synchronizing literals */ |
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 if ((size_t) (p - s->buffer->start) > sizeof("{1+}") - 1) { |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
664 p--; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
665 |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
666 if (*p == CR) { |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
667 p--; |
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 |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
670 if (*p == '}' && *(p - 1) == '+') { |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
671 s->quit = 1; |
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 } |
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_MAIL_PARSE_INVALID_COMMAND; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
676 } |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
677 } |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
678 |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
679 s->buffer->pos = p; |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
680 |
b38728495e1a
Mail: IMAP pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7842
diff
changeset
|
681 return NGX_AGAIN; |
527 | 682 } |
683 | |
684 | |
1477 | 685 ngx_int_t |
686 ngx_mail_smtp_parse_command(ngx_mail_session_t *s) | |
527 | 687 { |
688 u_char ch, *p, *c, c0, c1, c2, c3; | |
689 ngx_str_t *arg; | |
690 enum { | |
691 sw_start = 0, | |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
692 sw_command, |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
693 sw_invalid, |
527 | 694 sw_spaces_before_argument, |
695 sw_argument, | |
696 sw_almost_done | |
697 } state; | |
698 | |
699 state = s->state; | |
700 | |
9289
20017bff0de8
Mail: added some parsing debug logging.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9287
diff
changeset
|
701 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, |
20017bff0de8
Mail: added some parsing debug logging.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9287
diff
changeset
|
702 "smtp parse: %d", state); |
20017bff0de8
Mail: added some parsing debug logging.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9287
diff
changeset
|
703 |
527 | 704 for (p = s->buffer->pos; p < s->buffer->last; p++) { |
705 ch = *p; | |
706 | |
707 switch (state) { | |
708 | |
1136 | 709 /* SMTP command */ |
527 | 710 case sw_start: |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
711 s->cmd_start = p; |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
712 state = sw_command; |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
713 |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
714 /* fall through */ |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
715 |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
716 case sw_command: |
527 | 717 if (ch == ' ' || ch == CR || ch == LF) { |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
718 c = s->cmd_start; |
527 | 719 |
720 if (p - c == 4) { | |
721 | |
722 c0 = ngx_toupper(c[0]); | |
723 c1 = ngx_toupper(c[1]); | |
724 c2 = ngx_toupper(c[2]); | |
725 c3 = ngx_toupper(c[3]); | |
726 | |
1136 | 727 if (c0 == 'H' && c1 == 'E' && c2 == 'L' && c3 == 'O') |
527 | 728 { |
1136 | 729 s->command = NGX_SMTP_HELO; |
527 | 730 |
1136 | 731 } else if (c0 == 'E' && c1 == 'H' && c2 == 'L' && c3 == 'O') |
800 | 732 { |
1136 | 733 s->command = NGX_SMTP_EHLO; |
800 | 734 |
527 | 735 } else if (c0 == 'Q' && c1 == 'U' && c2 == 'I' && c3 == 'T') |
736 { | |
1136 | 737 s->command = NGX_SMTP_QUIT; |
527 | 738 |
809 | 739 } else if (c0 == 'A' && c1 == 'U' && c2 == 'T' && c3 == 'H') |
740 { | |
1136 | 741 s->command = NGX_SMTP_AUTH; |
809 | 742 |
527 | 743 } else if (c0 == 'N' && c1 == 'O' && c2 == 'O' && c3 == 'P') |
744 { | |
1136 | 745 s->command = NGX_SMTP_NOOP; |
746 | |
747 } else if (c0 == 'M' && c1 == 'A' && c2 == 'I' && c3 == 'L') | |
583 | 748 { |
1136 | 749 s->command = NGX_SMTP_MAIL; |
750 | |
751 } else if (c0 == 'R' && c1 == 'S' && c2 == 'E' && c3 == 'T') | |
752 { | |
753 s->command = NGX_SMTP_RSET; | |
754 | |
1322 | 755 } else if (c0 == 'R' && c1 == 'C' && c2 == 'P' && c3 == 'T') |
756 { | |
757 s->command = NGX_SMTP_RCPT; | |
758 | |
759 } else if (c0 == 'V' && c1 == 'R' && c2 == 'F' && c3 == 'Y') | |
760 { | |
761 s->command = NGX_SMTP_VRFY; | |
762 | |
763 } else if (c0 == 'E' && c1 == 'X' && c2 == 'P' && c3 == 'N') | |
764 { | |
765 s->command = NGX_SMTP_EXPN; | |
766 | |
767 } else if (c0 == 'H' && c1 == 'E' && c2 == 'L' && c3 == 'P') | |
768 { | |
769 s->command = NGX_SMTP_HELP; | |
770 | |
527 | 771 } else { |
772 goto invalid; | |
773 } | |
1322 | 774 #if (NGX_MAIL_SSL) |
775 } else if (p - c == 8) { | |
527 | 776 |
1322 | 777 if ((c[0] == 'S'|| c[0] == 's') |
778 && (c[1] == 'T'|| c[1] == 't') | |
779 && (c[2] == 'A'|| c[2] == 'a') | |
780 && (c[3] == 'R'|| c[3] == 'r') | |
781 && (c[4] == 'T'|| c[4] == 't') | |
782 && (c[5] == 'T'|| c[5] == 't') | |
783 && (c[6] == 'L'|| c[6] == 'l') | |
784 && (c[7] == 'S'|| c[7] == 's')) | |
785 { | |
786 s->command = NGX_SMTP_STARTTLS; | |
787 | |
788 } else { | |
789 goto invalid; | |
790 } | |
791 #endif | |
527 | 792 } else { |
793 goto invalid; | |
794 } | |
795 | |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
796 s->cmd.data = s->cmd_start; |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
797 s->cmd.len = p - s->cmd_start; |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
798 |
527 | 799 switch (ch) { |
800 case ' ': | |
801 state = sw_spaces_before_argument; | |
802 break; | |
803 case CR: | |
804 state = sw_almost_done; | |
805 break; | |
806 case LF: | |
807 goto done; | |
808 } | |
809 break; | |
810 } | |
811 | |
812 if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) { | |
813 goto invalid; | |
814 } | |
815 | |
816 break; | |
817 | |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
818 case sw_invalid: |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
819 goto invalid; |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
820 |
527 | 821 case sw_spaces_before_argument: |
822 switch (ch) { | |
823 case ' ': | |
824 break; | |
825 case CR: | |
826 state = sw_almost_done; | |
827 break; | |
828 case LF: | |
829 goto done; | |
830 default: | |
2309 | 831 if (s->args.nelts <= 10) { |
527 | 832 state = sw_argument; |
833 s->arg_start = p; | |
834 break; | |
835 } | |
836 goto invalid; | |
837 } | |
838 break; | |
839 | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
840 case sw_argument: |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
841 switch (ch) { |
800 | 842 case ' ': |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
843 case CR: |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
844 case LF: |
501 | 845 arg = ngx_array_push(&s->args); |
846 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
|
847 return NGX_ERROR; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
848 } |
527 | 849 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
|
850 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
|
851 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
|
852 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
853 switch (ch) { |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
854 case ' ': |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
855 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
|
856 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
857 case CR: |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
858 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
|
859 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
860 case LF: |
527 | 861 goto done; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
862 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
863 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
864 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
865 default: |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
866 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
867 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
868 break; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
869 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
870 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
|
871 switch (ch) { |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
872 case LF: |
527 | 873 goto done; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
874 default: |
527 | 875 goto invalid; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
876 } |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
877 } |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
878 } |
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
879 |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
417
diff
changeset
|
880 s->buffer->pos = p; |
527 | 881 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
|
882 |
527 | 883 return NGX_AGAIN; |
884 | |
885 done: | |
886 | |
887 s->buffer->pos = p + 1; | |
1136 | 888 s->state = (s->command != NGX_SMTP_AUTH) ? sw_start : sw_argument; |
889 | |
527 | 890 return NGX_OK; |
891 | |
892 invalid: | |
893 | |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
894 s->state = sw_invalid; |
527 | 895 |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
896 /* skip invalid command till LF */ |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
897 |
7837
ba8a8299b904
Mail: optimized discarding invalid SMTP commands.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7836
diff
changeset
|
898 for ( /* void */ ; p < s->buffer->last; p++) { |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
899 if (*p == LF) { |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
900 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
|
901 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
|
902 return NGX_MAIL_PARSE_INVALID_COMMAND; |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
903 } |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
904 } |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
905 |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
906 s->buffer->pos = p; |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5246
diff
changeset
|
907 |
7836
6a81d96d3733
Mail: fixed handling of invalid SMTP commands split between reads.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6774
diff
changeset
|
908 return NGX_AGAIN; |
417
0526206251f6
nginx-0.0.10-2004-09-07-19:29:22 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
909 } |
1479 | 910 |
911 | |
912 ngx_int_t | |
913 ngx_mail_auth_parse(ngx_mail_session_t *s, ngx_connection_t *c) | |
914 { | |
915 ngx_str_t *arg; | |
916 | |
917 #if (NGX_MAIL_SSL) | |
918 if (ngx_mail_starttls_only(s, c)) { | |
919 return NGX_MAIL_PARSE_INVALID_COMMAND; | |
920 } | |
921 #endif | |
922 | |
5246
b6562f98bfd8
Mail: fixed possible uninitialized memory access.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4759
diff
changeset
|
923 if (s->args.nelts == 0) { |
b6562f98bfd8
Mail: fixed possible uninitialized memory access.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4759
diff
changeset
|
924 return NGX_MAIL_PARSE_INVALID_COMMAND; |
b6562f98bfd8
Mail: fixed possible uninitialized memory access.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4759
diff
changeset
|
925 } |
b6562f98bfd8
Mail: fixed possible uninitialized memory access.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4759
diff
changeset
|
926 |
1479 | 927 arg = s->args.elts; |
928 | |
929 if (arg[0].len == 5) { | |
930 | |
931 if (ngx_strncasecmp(arg[0].data, (u_char *) "LOGIN", 5) == 0) { | |
932 | |
933 if (s->args.nelts == 1) { | |
934 return NGX_MAIL_AUTH_LOGIN; | |
935 } | |
936 | |
2495
a59b26eee816
compatibility with Microsoft's
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
937 if (s->args.nelts == 2) { |
a59b26eee816
compatibility with Microsoft's
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
938 return NGX_MAIL_AUTH_LOGIN_USERNAME; |
a59b26eee816
compatibility with Microsoft's
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
939 } |
a59b26eee816
compatibility with Microsoft's
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
940 |
1479 | 941 return NGX_MAIL_PARSE_INVALID_COMMAND; |
942 } | |
943 | |
944 if (ngx_strncasecmp(arg[0].data, (u_char *) "PLAIN", 5) == 0) { | |
945 | |
9287
32d4582c484d
Mail: fixed EXTERNAL to be accepted only if enabled.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7843
diff
changeset
|
946 if (s->args.nelts == 1 || s->args.nelts == 2) { |
1479 | 947 return NGX_MAIL_AUTH_PLAIN; |
948 } | |
949 | |
9287
32d4582c484d
Mail: fixed EXTERNAL to be accepted only if enabled.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7843
diff
changeset
|
950 return NGX_MAIL_PARSE_INVALID_COMMAND; |
1479 | 951 } |
952 | |
953 return NGX_MAIL_PARSE_INVALID_COMMAND; | |
954 } | |
955 | |
9290
4538c1ffb0f8
Mail: added support for XOAUTH2 and OAUTHBEARER authentication.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9289
diff
changeset
|
956 if (arg[0].len == 7) { |
4538c1ffb0f8
Mail: added support for XOAUTH2 and OAUTHBEARER authentication.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9289
diff
changeset
|
957 |
4538c1ffb0f8
Mail: added support for XOAUTH2 and OAUTHBEARER authentication.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9289
diff
changeset
|
958 if (ngx_strncasecmp(arg[0].data, (u_char *) "XOAUTH2", 7) == 0) { |
4538c1ffb0f8
Mail: added support for XOAUTH2 and OAUTHBEARER authentication.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9289
diff
changeset
|
959 |
4538c1ffb0f8
Mail: added support for XOAUTH2 and OAUTHBEARER authentication.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9289
diff
changeset
|
960 if (s->args.nelts == 1 || s->args.nelts == 2) { |
4538c1ffb0f8
Mail: added support for XOAUTH2 and OAUTHBEARER authentication.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9289
diff
changeset
|
961 return NGX_MAIL_AUTH_XOAUTH2; |
4538c1ffb0f8
Mail: added support for XOAUTH2 and OAUTHBEARER authentication.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9289
diff
changeset
|
962 } |
4538c1ffb0f8
Mail: added support for XOAUTH2 and OAUTHBEARER authentication.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9289
diff
changeset
|
963 |
4538c1ffb0f8
Mail: added support for XOAUTH2 and OAUTHBEARER authentication.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9289
diff
changeset
|
964 return NGX_MAIL_PARSE_INVALID_COMMAND; |
4538c1ffb0f8
Mail: added support for XOAUTH2 and OAUTHBEARER authentication.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9289
diff
changeset
|
965 } |
4538c1ffb0f8
Mail: added support for XOAUTH2 and OAUTHBEARER authentication.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9289
diff
changeset
|
966 |
4538c1ffb0f8
Mail: added support for XOAUTH2 and OAUTHBEARER authentication.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9289
diff
changeset
|
967 return NGX_MAIL_PARSE_INVALID_COMMAND; |
4538c1ffb0f8
Mail: added support for XOAUTH2 and OAUTHBEARER authentication.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9289
diff
changeset
|
968 } |
4538c1ffb0f8
Mail: added support for XOAUTH2 and OAUTHBEARER authentication.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9289
diff
changeset
|
969 |
1479 | 970 if (arg[0].len == 8) { |
971 | |
6774
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
972 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
|
973 |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
974 if (s->args.nelts != 1) { |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
975 return NGX_MAIL_PARSE_INVALID_COMMAND; |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
976 } |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
977 |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
978 return NGX_MAIL_AUTH_CRAM_MD5; |
1479 | 979 } |
980 | |
6774
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
981 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
|
982 |
9287
32d4582c484d
Mail: fixed EXTERNAL to be accepted only if enabled.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7843
diff
changeset
|
983 if (s->args.nelts == 1 || s->args.nelts == 2) { |
6774
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
984 return NGX_MAIL_AUTH_EXTERNAL; |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
985 } |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
986 |
9287
32d4582c484d
Mail: fixed EXTERNAL to be accepted only if enabled.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7843
diff
changeset
|
987 return NGX_MAIL_PARSE_INVALID_COMMAND; |
1479 | 988 } |
6774
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
989 |
bcb107bb89cd
Mail: support SASL EXTERNAL (RFC 4422).
Rob N ★ <robn@fastmail.com>
parents:
5398
diff
changeset
|
990 return NGX_MAIL_PARSE_INVALID_COMMAND; |
1479 | 991 } |
992 | |
9290
4538c1ffb0f8
Mail: added support for XOAUTH2 and OAUTHBEARER authentication.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9289
diff
changeset
|
993 if (arg[0].len == 11) { |
4538c1ffb0f8
Mail: added support for XOAUTH2 and OAUTHBEARER authentication.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9289
diff
changeset
|
994 |
4538c1ffb0f8
Mail: added support for XOAUTH2 and OAUTHBEARER authentication.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9289
diff
changeset
|
995 if (ngx_strncasecmp(arg[0].data, (u_char *) "OAUTHBEARER", 11) == 0) { |
4538c1ffb0f8
Mail: added support for XOAUTH2 and OAUTHBEARER authentication.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9289
diff
changeset
|
996 |
4538c1ffb0f8
Mail: added support for XOAUTH2 and OAUTHBEARER authentication.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9289
diff
changeset
|
997 if (s->args.nelts == 1 || s->args.nelts == 2) { |
4538c1ffb0f8
Mail: added support for XOAUTH2 and OAUTHBEARER authentication.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9289
diff
changeset
|
998 return NGX_MAIL_AUTH_OAUTHBEARER; |
4538c1ffb0f8
Mail: added support for XOAUTH2 and OAUTHBEARER authentication.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9289
diff
changeset
|
999 } |
4538c1ffb0f8
Mail: added support for XOAUTH2 and OAUTHBEARER authentication.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9289
diff
changeset
|
1000 |
4538c1ffb0f8
Mail: added support for XOAUTH2 and OAUTHBEARER authentication.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9289
diff
changeset
|
1001 return NGX_MAIL_PARSE_INVALID_COMMAND; |
4538c1ffb0f8
Mail: added support for XOAUTH2 and OAUTHBEARER authentication.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9289
diff
changeset
|
1002 } |
4538c1ffb0f8
Mail: added support for XOAUTH2 and OAUTHBEARER authentication.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9289
diff
changeset
|
1003 |
4538c1ffb0f8
Mail: added support for XOAUTH2 and OAUTHBEARER authentication.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9289
diff
changeset
|
1004 return NGX_MAIL_PARSE_INVALID_COMMAND; |
4538c1ffb0f8
Mail: added support for XOAUTH2 and OAUTHBEARER authentication.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9289
diff
changeset
|
1005 } |
4538c1ffb0f8
Mail: added support for XOAUTH2 and OAUTHBEARER authentication.
Maxim Dounin <mdounin@mdounin.ru>
parents:
9289
diff
changeset
|
1006 |
1479 | 1007 return NGX_MAIL_PARSE_INVALID_COMMAND; |
1008 } |