Mercurial > hg > nginx-quic
annotate src/mail/ngx_mail_proxy_module.c @ 8270:c57b6fc90f90 quic
QUIC: fixed header protection macro name.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Wed, 30 Dec 2020 20:47:35 +0300 |
parents | d63c5373b5ba |
children | da0a85e91587 |
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:
426
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:
426
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:
426
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:
426
diff
changeset
|
6 |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
7 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
8 #include <ngx_config.h> |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
9 #include <ngx_core.h> |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
10 #include <ngx_event.h> |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
11 #include <ngx_event_connect.h> |
1136 | 12 #include <ngx_mail.h> |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
13 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
14 |
521 | 15 typedef struct { |
16 ngx_flag_t enable; | |
857 | 17 ngx_flag_t pass_error_message; |
1136 | 18 ngx_flag_t xclient; |
8178
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
19 ngx_flag_t smtp_auth; |
539 | 20 size_t buffer_size; |
21 ngx_msec_t timeout; | |
1136 | 22 } ngx_mail_proxy_conf_t; |
521 | 23 |
24 | |
1136 | 25 static void ngx_mail_proxy_block_read(ngx_event_t *rev); |
26 static void ngx_mail_proxy_pop3_handler(ngx_event_t *rev); | |
27 static void ngx_mail_proxy_imap_handler(ngx_event_t *rev); | |
28 static void ngx_mail_proxy_smtp_handler(ngx_event_t *rev); | |
29 static void ngx_mail_proxy_dummy_handler(ngx_event_t *ev); | |
30 static ngx_int_t ngx_mail_proxy_read_response(ngx_mail_session_t *s, | |
663 | 31 ngx_uint_t state); |
1136 | 32 static void ngx_mail_proxy_handler(ngx_event_t *ev); |
33 static void ngx_mail_proxy_upstream_error(ngx_mail_session_t *s); | |
34 static void ngx_mail_proxy_internal_server_error(ngx_mail_session_t *s); | |
35 static void ngx_mail_proxy_close_session(ngx_mail_session_t *s); | |
36 static void *ngx_mail_proxy_create_conf(ngx_conf_t *cf); | |
37 static char *ngx_mail_proxy_merge_conf(ngx_conf_t *cf, void *parent, | |
521 | 38 void *child); |
39 | |
40 | |
1136 | 41 static ngx_command_t ngx_mail_proxy_commands[] = { |
539 | 42 |
521 | 43 { ngx_string("proxy"), |
1136 | 44 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, |
521 | 45 ngx_conf_set_flag_slot, |
1136 | 46 NGX_MAIL_SRV_CONF_OFFSET, |
47 offsetof(ngx_mail_proxy_conf_t, enable), | |
521 | 48 NULL }, |
49 | |
539 | 50 { ngx_string("proxy_buffer"), |
1136 | 51 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, |
539 | 52 ngx_conf_set_size_slot, |
1136 | 53 NGX_MAIL_SRV_CONF_OFFSET, |
54 offsetof(ngx_mail_proxy_conf_t, buffer_size), | |
539 | 55 NULL }, |
56 | |
57 { ngx_string("proxy_timeout"), | |
1136 | 58 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, |
539 | 59 ngx_conf_set_msec_slot, |
1136 | 60 NGX_MAIL_SRV_CONF_OFFSET, |
61 offsetof(ngx_mail_proxy_conf_t, timeout), | |
539 | 62 NULL }, |
63 | |
857 | 64 { ngx_string("proxy_pass_error_message"), |
4273
e444e8f6538b
Fixed NGX_CONF_TAKE1/NGX_CONF_FLAG misuse.
Sergey Budnevitch <sb@waeme.net>
parents:
3516
diff
changeset
|
65 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, |
857 | 66 ngx_conf_set_flag_slot, |
1136 | 67 NGX_MAIL_SRV_CONF_OFFSET, |
68 offsetof(ngx_mail_proxy_conf_t, pass_error_message), | |
69 NULL }, | |
70 | |
71 { ngx_string("xclient"), | |
72 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, | |
73 ngx_conf_set_flag_slot, | |
74 NGX_MAIL_SRV_CONF_OFFSET, | |
75 offsetof(ngx_mail_proxy_conf_t, xclient), | |
857 | 76 NULL }, |
77 | |
8178
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
78 { ngx_string("proxy_smtp_auth"), |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
79 NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
80 ngx_conf_set_flag_slot, |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
81 NGX_MAIL_SRV_CONF_OFFSET, |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
82 offsetof(ngx_mail_proxy_conf_t, smtp_auth), |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
83 NULL }, |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
84 |
521 | 85 ngx_null_command |
86 }; | |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
87 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
88 |
1136 | 89 static ngx_mail_module_t ngx_mail_proxy_module_ctx = { |
1487
f69493e8faab
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
Igor Sysoev <igor@sysoev.ru>
parents:
1342
diff
changeset
|
90 NULL, /* protocol */ |
f69493e8faab
ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module
Igor Sysoev <igor@sysoev.ru>
parents:
1342
diff
changeset
|
91 |
521 | 92 NULL, /* create main configuration */ |
93 NULL, /* init main configuration */ | |
94 | |
1136 | 95 ngx_mail_proxy_create_conf, /* create server configuration */ |
96 ngx_mail_proxy_merge_conf /* merge server configuration */ | |
521 | 97 }; |
98 | |
99 | |
1136 | 100 ngx_module_t ngx_mail_proxy_module = { |
521 | 101 NGX_MODULE_V1, |
1136 | 102 &ngx_mail_proxy_module_ctx, /* module context */ |
103 ngx_mail_proxy_commands, /* module directives */ | |
104 NGX_MAIL_MODULE, /* module type */ | |
541 | 105 NULL, /* init master */ |
521 | 106 NULL, /* init module */ |
541 | 107 NULL, /* init process */ |
108 NULL, /* init thread */ | |
109 NULL, /* exit thread */ | |
110 NULL, /* exit process */ | |
111 NULL, /* exit master */ | |
112 NGX_MODULE_V1_PADDING | |
521 | 113 }; |
114 | |
115 | |
2440
939b40aa9ab4
update r2439: make clear name
Igor Sysoev <igor@sysoev.ru>
parents:
2438
diff
changeset
|
116 static u_char smtp_auth_ok[] = "235 2.0.0 OK" CRLF; |
1136 | 117 |
118 | |
521 | 119 void |
3269
f0d596e84634
rename ngx_peer_addr_t to ngx_addr_t
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
120 ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_addr_t *peer) |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
121 { |
527 | 122 ngx_int_t rc; |
1136 | 123 ngx_mail_proxy_ctx_t *p; |
124 ngx_mail_proxy_conf_t *pcf; | |
125 ngx_mail_core_srv_conf_t *cscf; | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
126 |
587 | 127 s->connection->log->action = "connecting to upstream"; |
128 | |
1136 | 129 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); |
587 | 130 |
1136 | 131 p = ngx_pcalloc(s->connection->pool, sizeof(ngx_mail_proxy_ctx_t)); |
501 | 132 if (p == NULL) { |
1136 | 133 ngx_mail_session_internal_server_error(s); |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
134 return; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
135 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
136 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
137 s->proxy = p; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
138 |
884 | 139 p->upstream.sockaddr = peer->sockaddr; |
140 p->upstream.socklen = peer->socklen; | |
141 p->upstream.name = &peer->name; | |
142 p->upstream.get = ngx_event_get_peer; | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
143 p->upstream.log = s->connection->log; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
144 p->upstream.log_error = NGX_ERROR_ERR; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
145 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
146 rc = ngx_event_connect_peer(&p->upstream); |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
147 |
543 | 148 if (rc == NGX_ERROR || rc == NGX_BUSY || rc == NGX_DECLINED) { |
1136 | 149 ngx_mail_proxy_internal_server_error(s); |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
150 return; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
151 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
152 |
527 | 153 ngx_add_timer(p->upstream.connection->read, cscf->timeout); |
154 | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
155 p->upstream.connection->data = s; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
156 p->upstream.connection->pool = s->connection->pool; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
157 |
1136 | 158 s->connection->read->handler = ngx_mail_proxy_block_read; |
159 p->upstream.connection->write->handler = ngx_mail_proxy_dummy_handler; | |
160 | |
161 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); | |
162 | |
163 s->proxy->buffer = ngx_create_temp_buf(s->connection->pool, | |
164 pcf->buffer_size); | |
165 if (s->proxy->buffer == NULL) { | |
166 ngx_mail_proxy_internal_server_error(s); | |
167 return; | |
168 } | |
169 | |
1981 | 170 s->out.len = 0; |
171 | |
1136 | 172 switch (s->protocol) { |
527 | 173 |
1136 | 174 case NGX_MAIL_POP3_PROTOCOL: |
175 p->upstream.connection->read->handler = ngx_mail_proxy_pop3_handler; | |
176 s->mail_state = ngx_pop3_start; | |
177 break; | |
527 | 178 |
1136 | 179 case NGX_MAIL_IMAP_PROTOCOL: |
180 p->upstream.connection->read->handler = ngx_mail_proxy_imap_handler; | |
181 s->mail_state = ngx_imap_start; | |
182 break; | |
183 | |
184 default: /* NGX_MAIL_SMTP_PROTOCOL */ | |
185 p->upstream.connection->read->handler = ngx_mail_proxy_smtp_handler; | |
186 s->mail_state = ngx_smtp_start; | |
187 break; | |
527 | 188 } |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
189 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
190 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
191 |
521 | 192 static void |
1136 | 193 ngx_mail_proxy_block_read(ngx_event_t *rev) |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
194 { |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
195 ngx_connection_t *c; |
1136 | 196 ngx_mail_session_t *s; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
197 |
1136 | 198 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail proxy block read"); |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
199 |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2311
diff
changeset
|
200 if (ngx_handle_read_event(rev, 0) != NGX_OK) { |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
201 c = rev->data; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
202 s = c->data; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
203 |
1136 | 204 ngx_mail_proxy_close_session(s); |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
205 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
206 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
207 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
208 |
521 | 209 static void |
1136 | 210 ngx_mail_proxy_pop3_handler(ngx_event_t *rev) |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
211 { |
539 | 212 u_char *p; |
213 ngx_int_t rc; | |
214 ngx_str_t line; | |
215 ngx_connection_t *c; | |
1136 | 216 ngx_mail_session_t *s; |
217 ngx_mail_proxy_conf_t *pcf; | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
218 |
1136 | 219 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, |
220 "mail proxy pop3 auth handler"); | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
221 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
222 c = rev->data; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
223 s = c->data; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
224 |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
225 if (rev->timedout) { |
527 | 226 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, |
227 "upstream timed out"); | |
577 | 228 c->timedout = 1; |
1136 | 229 ngx_mail_proxy_internal_server_error(s); |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
230 return; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
231 } |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
232 |
1136 | 233 rc = ngx_mail_proxy_read_response(s, 0); |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
234 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
235 if (rc == NGX_AGAIN) { |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
236 return; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
237 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
238 |
571 | 239 if (rc == NGX_ERROR) { |
1136 | 240 ngx_mail_proxy_upstream_error(s); |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
241 return; |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
242 } |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
243 |
1136 | 244 switch (s->mail_state) { |
587 | 245 |
1136 | 246 case ngx_pop3_start: |
247 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail proxy send user"); | |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
248 |
587 | 249 s->connection->log->action = "sending user name to upstream"; |
250 | |
1136 | 251 line.len = sizeof("USER ") - 1 + s->login.len + 2; |
2049 | 252 line.data = ngx_pnalloc(c->pool, line.len); |
527 | 253 if (line.data == NULL) { |
1136 | 254 ngx_mail_proxy_internal_server_error(s); |
527 | 255 return; |
256 } | |
257 | |
1136 | 258 p = ngx_cpymem(line.data, "USER ", sizeof("USER ") - 1); |
259 p = ngx_cpymem(p, s->login.data, s->login.len); | |
260 *p++ = CR; *p = LF; | |
527 | 261 |
1136 | 262 s->mail_state = ngx_pop3_user; |
527 | 263 break; |
264 | |
1136 | 265 case ngx_pop3_user: |
266 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail proxy send pass"); | |
527 | 267 |
587 | 268 s->connection->log->action = "sending password to upstream"; |
269 | |
1136 | 270 line.len = sizeof("PASS ") - 1 + s->passwd.len + 2; |
2049 | 271 line.data = ngx_pnalloc(c->pool, line.len); |
501 | 272 if (line.data == NULL) { |
1136 | 273 ngx_mail_proxy_internal_server_error(s); |
527 | 274 return; |
275 } | |
276 | |
1136 | 277 p = ngx_cpymem(line.data, "PASS ", sizeof("PASS ") - 1); |
278 p = ngx_cpymem(p, s->passwd.data, s->passwd.len); | |
527 | 279 *p++ = CR; *p = LF; |
280 | |
1136 | 281 s->mail_state = ngx_pop3_passwd; |
527 | 282 break; |
283 | |
1136 | 284 case ngx_pop3_passwd: |
285 s->connection->read->handler = ngx_mail_proxy_handler; | |
286 s->connection->write->handler = ngx_mail_proxy_handler; | |
287 rev->handler = ngx_mail_proxy_handler; | |
288 c->write->handler = ngx_mail_proxy_handler; | |
663 | 289 |
1136 | 290 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); |
663 | 291 ngx_add_timer(s->connection->read, pcf->timeout); |
292 ngx_del_timer(c->read); | |
293 | |
294 c->log->action = NULL; | |
295 ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in"); | |
296 | |
1136 | 297 ngx_mail_proxy_handler(s->connection->write); |
663 | 298 |
299 return; | |
300 | |
527 | 301 default: |
302 #if (NGX_SUPPRESS_WARN) | |
3516
dd1570b6f237
ngx_str_set() and ngx_str_null()
Igor Sysoev <igor@sysoev.ru>
parents:
3505
diff
changeset
|
303 ngx_str_null(&line); |
527 | 304 #endif |
305 break; | |
306 } | |
307 | |
539 | 308 if (c->send(c, line.data, line.len) < (ssize_t) line.len) { |
527 | 309 /* |
310 * we treat the incomplete sending as NGX_ERROR | |
311 * because it is very strange here | |
312 */ | |
1136 | 313 ngx_mail_proxy_internal_server_error(s); |
527 | 314 return; |
315 } | |
316 | |
317 s->proxy->buffer->pos = s->proxy->buffer->start; | |
318 s->proxy->buffer->last = s->proxy->buffer->start; | |
319 } | |
320 | |
321 | |
322 static void | |
1136 | 323 ngx_mail_proxy_imap_handler(ngx_event_t *rev) |
527 | 324 { |
539 | 325 u_char *p; |
326 ngx_int_t rc; | |
327 ngx_str_t line; | |
328 ngx_connection_t *c; | |
1136 | 329 ngx_mail_session_t *s; |
330 ngx_mail_proxy_conf_t *pcf; | |
527 | 331 |
1136 | 332 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, |
333 "mail proxy imap auth handler"); | |
527 | 334 |
335 c = rev->data; | |
336 s = c->data; | |
337 | |
338 if (rev->timedout) { | |
339 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, | |
340 "upstream timed out"); | |
577 | 341 c->timedout = 1; |
1136 | 342 ngx_mail_proxy_internal_server_error(s); |
527 | 343 return; |
344 } | |
345 | |
1136 | 346 rc = ngx_mail_proxy_read_response(s, s->mail_state); |
527 | 347 |
348 if (rc == NGX_AGAIN) { | |
349 return; | |
350 } | |
351 | |
571 | 352 if (rc == NGX_ERROR) { |
1136 | 353 ngx_mail_proxy_upstream_error(s); |
527 | 354 return; |
355 } | |
356 | |
1136 | 357 switch (s->mail_state) { |
527 | 358 |
1136 | 359 case ngx_imap_start: |
360 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, | |
361 "mail proxy send login"); | |
527 | 362 |
1136 | 363 s->connection->log->action = "sending LOGIN command to upstream"; |
587 | 364 |
1136 | 365 line.len = s->tag.len + sizeof("LOGIN ") - 1 |
366 + 1 + NGX_SIZE_T_LEN + 1 + 2; | |
2049 | 367 line.data = ngx_pnalloc(c->pool, line.len); |
527 | 368 if (line.data == NULL) { |
1136 | 369 ngx_mail_proxy_internal_server_error(s); |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
370 return; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
371 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
372 |
1136 | 373 line.len = ngx_sprintf(line.data, "%VLOGIN {%uz}" CRLF, |
374 &s->tag, s->login.len) | |
375 - line.data; | |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
376 |
1136 | 377 s->mail_state = ngx_imap_login; |
527 | 378 break; |
379 | |
1136 | 380 case ngx_imap_login: |
381 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail proxy send user"); | |
382 | |
383 s->connection->log->action = "sending user name to upstream"; | |
384 | |
385 line.len = s->login.len + 1 + 1 + NGX_SIZE_T_LEN + 1 + 2; | |
2049 | 386 line.data = ngx_pnalloc(c->pool, line.len); |
1136 | 387 if (line.data == NULL) { |
388 ngx_mail_proxy_internal_server_error(s); | |
389 return; | |
390 } | |
391 | |
392 line.len = ngx_sprintf(line.data, "%V {%uz}" CRLF, | |
393 &s->login, s->passwd.len) | |
394 - line.data; | |
395 | |
396 s->mail_state = ngx_imap_user; | |
397 break; | |
398 | |
399 case ngx_imap_user: | |
400 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, | |
401 "mail proxy send passwd"); | |
527 | 402 |
587 | 403 s->connection->log->action = "sending password to upstream"; |
404 | |
1136 | 405 line.len = s->passwd.len + 2; |
2049 | 406 line.data = ngx_pnalloc(c->pool, line.len); |
527 | 407 if (line.data == NULL) { |
1136 | 408 ngx_mail_proxy_internal_server_error(s); |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
409 return; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
410 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
411 |
1136 | 412 p = ngx_cpymem(line.data, s->passwd.data, s->passwd.len); |
527 | 413 *p++ = CR; *p = LF; |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
414 |
1136 | 415 s->mail_state = ngx_imap_passwd; |
527 | 416 break; |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
417 |
1136 | 418 case ngx_imap_passwd: |
419 s->connection->read->handler = ngx_mail_proxy_handler; | |
420 s->connection->write->handler = ngx_mail_proxy_handler; | |
421 rev->handler = ngx_mail_proxy_handler; | |
422 c->write->handler = ngx_mail_proxy_handler; | |
663 | 423 |
1136 | 424 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); |
663 | 425 ngx_add_timer(s->connection->read, pcf->timeout); |
426 ngx_del_timer(c->read); | |
427 | |
428 c->log->action = NULL; | |
429 ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in"); | |
430 | |
1136 | 431 ngx_mail_proxy_handler(s->connection->write); |
663 | 432 |
433 return; | |
434 | |
527 | 435 default: |
436 #if (NGX_SUPPRESS_WARN) | |
3516
dd1570b6f237
ngx_str_set() and ngx_str_null()
Igor Sysoev <igor@sysoev.ru>
parents:
3505
diff
changeset
|
437 ngx_str_null(&line); |
527 | 438 #endif |
439 break; | |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
440 } |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
441 |
539 | 442 if (c->send(c, line.data, line.len) < (ssize_t) line.len) { |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
443 /* |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
444 * we treat the incomplete sending as NGX_ERROR |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
445 * because it is very strange here |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
446 */ |
1136 | 447 ngx_mail_proxy_internal_server_error(s); |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
448 return; |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
449 } |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
450 |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
451 s->proxy->buffer->pos = s->proxy->buffer->start; |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
452 s->proxy->buffer->last = s->proxy->buffer->start; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
453 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
454 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
455 |
521 | 456 static void |
1136 | 457 ngx_mail_proxy_smtp_handler(ngx_event_t *rev) |
458 { | |
459 u_char *p; | |
460 ngx_int_t rc; | |
8178
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
461 ngx_str_t line, auth, encoded; |
2309 | 462 ngx_buf_t *b; |
1136 | 463 ngx_connection_t *c; |
464 ngx_mail_session_t *s; | |
465 ngx_mail_proxy_conf_t *pcf; | |
466 ngx_mail_core_srv_conf_t *cscf; | |
467 | |
468 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, | |
469 "mail proxy smtp auth handler"); | |
470 | |
471 c = rev->data; | |
472 s = c->data; | |
473 | |
474 if (rev->timedout) { | |
475 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, | |
476 "upstream timed out"); | |
477 c->timedout = 1; | |
478 ngx_mail_proxy_internal_server_error(s); | |
479 return; | |
480 } | |
481 | |
482 rc = ngx_mail_proxy_read_response(s, s->mail_state); | |
483 | |
484 if (rc == NGX_AGAIN) { | |
485 return; | |
486 } | |
487 | |
488 if (rc == NGX_ERROR) { | |
489 ngx_mail_proxy_upstream_error(s); | |
490 return; | |
491 } | |
492 | |
493 switch (s->mail_state) { | |
494 | |
495 case ngx_smtp_start: | |
496 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail proxy send ehlo"); | |
497 | |
498 s->connection->log->action = "sending HELO/EHLO to upstream"; | |
499 | |
500 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); | |
501 | |
502 line.len = sizeof("HELO ") - 1 + cscf->server_name.len + 2; | |
2049 | 503 line.data = ngx_pnalloc(c->pool, line.len); |
1136 | 504 if (line.data == NULL) { |
505 ngx_mail_proxy_internal_server_error(s); | |
506 return; | |
507 } | |
508 | |
509 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); | |
510 | |
511 p = ngx_cpymem(line.data, | |
512 ((s->esmtp || pcf->xclient) ? "EHLO " : "HELO "), | |
513 sizeof("HELO ") - 1); | |
514 | |
515 p = ngx_cpymem(p, cscf->server_name.data, cscf->server_name.len); | |
516 *p++ = CR; *p = LF; | |
517 | |
2309 | 518 if (pcf->xclient) { |
519 s->mail_state = ngx_smtp_helo_xclient; | |
520 | |
521 } else if (s->auth_method == NGX_MAIL_AUTH_NONE) { | |
522 s->mail_state = ngx_smtp_helo_from; | |
523 | |
8178
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
524 } else if (pcf->smtp_auth) { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
525 s->mail_state = ngx_smtp_helo_auth; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
526 |
2309 | 527 } else { |
528 s->mail_state = ngx_smtp_helo; | |
529 } | |
1136 | 530 |
531 break; | |
532 | |
2309 | 533 case ngx_smtp_helo_xclient: |
1136 | 534 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, |
535 "mail proxy send xclient"); | |
536 | |
537 s->connection->log->action = "sending XCLIENT to upstream"; | |
538 | |
2497 | 539 line.len = sizeof("XCLIENT ADDR= LOGIN= NAME=" |
1892
057d362ee50e
resolver in smtp proxy module
Igor Sysoev <igor@sysoev.ru>
parents:
1487
diff
changeset
|
540 CRLF) - 1 |
057d362ee50e
resolver in smtp proxy module
Igor Sysoev <igor@sysoev.ru>
parents:
1487
diff
changeset
|
541 + s->connection->addr_text.len + s->login.len + s->host.len; |
1136 | 542 |
5522
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
543 #if (NGX_HAVE_INET6) |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
544 if (s->connection->sockaddr->sa_family == AF_INET6) { |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
545 line.len += sizeof("IPV6:") - 1; |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
546 } |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
547 #endif |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
548 |
2049 | 549 line.data = ngx_pnalloc(c->pool, line.len); |
1136 | 550 if (line.data == NULL) { |
551 ngx_mail_proxy_internal_server_error(s); | |
552 return; | |
553 } | |
554 | |
5522
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
555 p = ngx_cpymem(line.data, "XCLIENT ADDR=", sizeof("XCLIENT ADDR=") - 1); |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
556 |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
557 #if (NGX_HAVE_INET6) |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
558 if (s->connection->sockaddr->sa_family == AF_INET6) { |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
559 p = ngx_cpymem(p, "IPV6:", sizeof("IPV6:") - 1); |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
560 } |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
561 #endif |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
562 |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
563 p = ngx_copy(p, s->connection->addr_text.data, |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
564 s->connection->addr_text.len); |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
565 |
8178
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
566 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
567 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
568 if (s->login.len && !pcf->smtp_auth) { |
5522
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
569 p = ngx_cpymem(p, " LOGIN=", sizeof(" LOGIN=") - 1); |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
570 p = ngx_copy(p, s->login.data, s->login.len); |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
571 } |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
572 |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
573 p = ngx_cpymem(p, " NAME=", sizeof(" NAME=") - 1); |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
574 p = ngx_copy(p, s->host.data, s->host.len); |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
575 |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
576 *p++ = CR; *p++ = LF; |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
577 |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
578 line.len = p - line.data; |
2309 | 579 |
2497 | 580 if (s->smtp_helo.len) { |
581 s->mail_state = ngx_smtp_xclient_helo; | |
582 | |
583 } else if (s->auth_method == NGX_MAIL_AUTH_NONE) { | |
584 s->mail_state = ngx_smtp_xclient_from; | |
585 | |
8178
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
586 } else if (pcf->smtp_auth) { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
587 s->mail_state = ngx_smtp_xclient_auth; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
588 |
2497 | 589 } else { |
590 s->mail_state = ngx_smtp_xclient; | |
591 } | |
592 | |
593 break; | |
594 | |
595 case ngx_smtp_xclient_helo: | |
596 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, | |
597 "mail proxy send client ehlo"); | |
598 | |
599 s->connection->log->action = "sending client HELO/EHLO to upstream"; | |
600 | |
601 line.len = sizeof("HELO " CRLF) - 1 + s->smtp_helo.len; | |
602 | |
603 line.data = ngx_pnalloc(c->pool, line.len); | |
604 if (line.data == NULL) { | |
605 ngx_mail_proxy_internal_server_error(s); | |
606 return; | |
607 } | |
608 | |
609 line.len = ngx_sprintf(line.data, | |
610 ((s->esmtp) ? "EHLO %V" CRLF : "HELO %V" CRLF), | |
611 &s->smtp_helo) | |
612 - line.data; | |
613 | |
8178
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
614 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
615 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
616 if (s->auth_method == NGX_MAIL_AUTH_NONE) { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
617 s->mail_state = ngx_smtp_helo_from; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
618 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
619 } else if (pcf->smtp_auth) { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
620 s->mail_state = ngx_smtp_helo_auth; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
621 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
622 } else { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
623 s->mail_state = ngx_smtp_helo; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
624 } |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
625 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
626 break; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
627 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
628 case ngx_smtp_helo_auth: |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
629 case ngx_smtp_xclient_auth: |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
630 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
631 "mail proxy send auth"); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
632 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
633 s->connection->log->action = "sending AUTH to upstream"; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
634 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
635 if (s->passwd.data == NULL) { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
636 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
637 "no password available"); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
638 ngx_mail_proxy_internal_server_error(s); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
639 return; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
640 } |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
641 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
642 auth.len = 1 + s->login.len + 1 + s->passwd.len; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
643 auth.data = ngx_pnalloc(c->pool, auth.len); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
644 if (auth.data == NULL) { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
645 ngx_mail_proxy_internal_server_error(s); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
646 return; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
647 } |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
648 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
649 auth.len = ngx_sprintf(auth.data, "%Z%V%Z%V", &s->login, &s->passwd) |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
650 - auth.data; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
651 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
652 line.len = sizeof("AUTH PLAIN " CRLF) - 1 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
653 + ngx_base64_encoded_length(auth.len); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
654 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
655 line.data = ngx_pnalloc(c->pool, line.len); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
656 if (line.data == NULL) { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
657 ngx_mail_proxy_internal_server_error(s); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
658 return; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
659 } |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
660 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
661 encoded.data = ngx_cpymem(line.data, "AUTH PLAIN ", |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
662 sizeof("AUTH PLAIN ") - 1); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
663 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
664 ngx_encode_base64(&encoded, &auth); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
665 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
666 p = encoded.data + encoded.len; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
667 *p++ = CR; *p = LF; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
668 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
669 s->mail_state = ngx_smtp_auth_plain; |
2309 | 670 |
671 break; | |
672 | |
673 case ngx_smtp_helo_from: | |
674 case ngx_smtp_xclient_from: | |
675 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, | |
676 "mail proxy send mail from"); | |
677 | |
678 s->connection->log->action = "sending MAIL FROM to upstream"; | |
679 | |
680 line.len = s->smtp_from.len + sizeof(CRLF) - 1; | |
681 line.data = ngx_pnalloc(c->pool, line.len); | |
682 if (line.data == NULL) { | |
683 ngx_mail_proxy_internal_server_error(s); | |
684 return; | |
1136 | 685 } |
686 | |
2309 | 687 p = ngx_cpymem(line.data, s->smtp_from.data, s->smtp_from.len); |
688 *p++ = CR; *p = LF; | |
689 | |
690 s->mail_state = ngx_smtp_from; | |
691 | |
1136 | 692 break; |
693 | |
2309 | 694 case ngx_smtp_from: |
695 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, | |
696 "mail proxy send rcpt to"); | |
697 | |
698 s->connection->log->action = "sending RCPT TO to upstream"; | |
699 | |
700 line.len = s->smtp_to.len + sizeof(CRLF) - 1; | |
701 line.data = ngx_pnalloc(c->pool, line.len); | |
702 if (line.data == NULL) { | |
703 ngx_mail_proxy_internal_server_error(s); | |
704 return; | |
705 } | |
706 | |
707 p = ngx_cpymem(line.data, s->smtp_to.data, s->smtp_to.len); | |
708 *p++ = CR; *p = LF; | |
709 | |
710 s->mail_state = ngx_smtp_to; | |
1136 | 711 |
2309 | 712 break; |
713 | |
714 case ngx_smtp_helo: | |
715 case ngx_smtp_xclient: | |
8178
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
716 case ngx_smtp_auth_plain: |
2309 | 717 case ngx_smtp_to: |
718 | |
719 b = s->proxy->buffer; | |
1136 | 720 |
2309 | 721 if (s->auth_method == NGX_MAIL_AUTH_NONE) { |
2311
6bad42a41dd8
do not close session if SMTP backend returned an error on RCPT TO
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
722 b->pos = b->start; |
2309 | 723 |
724 } else { | |
2440
939b40aa9ab4
update r2439: make clear name
Igor Sysoev <igor@sysoev.ru>
parents:
2438
diff
changeset
|
725 ngx_memcpy(b->start, smtp_auth_ok, sizeof(smtp_auth_ok) - 1); |
939b40aa9ab4
update r2439: make clear name
Igor Sysoev <igor@sysoev.ru>
parents:
2438
diff
changeset
|
726 b->last = b->start + sizeof(smtp_auth_ok) - 1; |
2309 | 727 } |
728 | |
1136 | 729 s->connection->read->handler = ngx_mail_proxy_handler; |
730 s->connection->write->handler = ngx_mail_proxy_handler; | |
731 rev->handler = ngx_mail_proxy_handler; | |
732 c->write->handler = ngx_mail_proxy_handler; | |
733 | |
734 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); | |
735 ngx_add_timer(s->connection->read, pcf->timeout); | |
736 ngx_del_timer(c->read); | |
737 | |
738 c->log->action = NULL; | |
739 ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in"); | |
740 | |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
741 if (s->buffer->pos == s->buffer->last) { |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
742 ngx_mail_proxy_handler(s->connection->write); |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
743 |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
744 } else { |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
745 ngx_mail_proxy_handler(c->write); |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
746 } |
1136 | 747 |
748 return; | |
749 | |
750 default: | |
751 #if (NGX_SUPPRESS_WARN) | |
3516
dd1570b6f237
ngx_str_set() and ngx_str_null()
Igor Sysoev <igor@sysoev.ru>
parents:
3505
diff
changeset
|
752 ngx_str_null(&line); |
1136 | 753 #endif |
754 break; | |
755 } | |
756 | |
757 if (c->send(c, line.data, line.len) < (ssize_t) line.len) { | |
758 /* | |
759 * we treat the incomplete sending as NGX_ERROR | |
760 * because it is very strange here | |
761 */ | |
762 ngx_mail_proxy_internal_server_error(s); | |
763 return; | |
764 } | |
765 | |
766 s->proxy->buffer->pos = s->proxy->buffer->start; | |
767 s->proxy->buffer->last = s->proxy->buffer->start; | |
768 } | |
769 | |
770 | |
771 static void | |
772 ngx_mail_proxy_dummy_handler(ngx_event_t *wev) | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
773 { |
583 | 774 ngx_connection_t *c; |
1136 | 775 ngx_mail_session_t *s; |
583 | 776 |
1136 | 777 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, wev->log, 0, "mail proxy dummy handler"); |
583 | 778 |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2311
diff
changeset
|
779 if (ngx_handle_write_event(wev, 0) != NGX_OK) { |
583 | 780 c = wev->data; |
781 s = c->data; | |
782 | |
1136 | 783 ngx_mail_proxy_close_session(s); |
583 | 784 } |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
785 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
786 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
787 |
521 | 788 static ngx_int_t |
1136 | 789 ngx_mail_proxy_read_response(ngx_mail_session_t *s, ngx_uint_t state) |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
790 { |
5399
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
791 u_char *p, *m; |
857 | 792 ssize_t n; |
793 ngx_buf_t *b; | |
1136 | 794 ngx_mail_proxy_conf_t *pcf; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
795 |
587 | 796 s->connection->log->action = "reading response from upstream"; |
797 | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
798 b = s->proxy->buffer; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
799 |
539 | 800 n = s->proxy->upstream.connection->recv(s->proxy->upstream.connection, |
801 b->last, b->end - b->last); | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
802 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
803 if (n == NGX_ERROR || n == 0) { |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
804 return NGX_ERROR; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
805 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
806 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
807 if (n == NGX_AGAIN) { |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
808 return NGX_AGAIN; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
809 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
810 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
811 b->last += n; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
812 |
3505
c631ef8beaaa
Zimbra IMAP server may return only 4 bytes: "+ \r\n"
Igor Sysoev <igor@sysoev.ru>
parents:
3269
diff
changeset
|
813 if (b->last - b->pos < 4) { |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
814 return NGX_AGAIN; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
815 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
816 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
817 if (*(b->last - 2) != CR || *(b->last - 1) != LF) { |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
818 if (b->last == b->end) { |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
819 *(b->last - 1) = '\0'; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
820 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
821 "upstream sent too long response line: \"%s\"", |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
822 b->pos); |
571 | 823 return NGX_ERROR; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
824 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
825 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
826 return NGX_AGAIN; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
827 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
828 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
829 p = b->pos; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
830 |
1136 | 831 switch (s->protocol) { |
832 | |
833 case NGX_MAIL_POP3_PROTOCOL: | |
527 | 834 if (p[0] == '+' && p[1] == 'O' && p[2] == 'K') { |
835 return NGX_OK; | |
836 } | |
1136 | 837 break; |
527 | 838 |
1136 | 839 case NGX_MAIL_IMAP_PROTOCOL: |
663 | 840 switch (state) { |
841 | |
842 case ngx_imap_start: | |
527 | 843 if (p[0] == '*' && p[1] == ' ' && p[2] == 'O' && p[3] == 'K') { |
844 return NGX_OK; | |
845 } | |
663 | 846 break; |
527 | 847 |
663 | 848 case ngx_imap_login: |
849 case ngx_imap_user: | |
529 | 850 if (p[0] == '+') { |
527 | 851 return NGX_OK; |
852 } | |
663 | 853 break; |
854 | |
855 case ngx_imap_passwd: | |
856 if (ngx_strncmp(p, s->tag.data, s->tag.len) == 0) { | |
857 p += s->tag.len; | |
858 if (p[0] == 'O' && p[1] == 'K') { | |
859 return NGX_OK; | |
860 } | |
861 } | |
862 break; | |
527 | 863 } |
1136 | 864 |
865 break; | |
866 | |
867 default: /* NGX_MAIL_SMTP_PROTOCOL */ | |
5399
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
868 |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
869 if (p[3] == '-') { |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
870 /* multiline reply, check if we got last line */ |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
871 |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
872 m = b->last - (sizeof(CRLF "200" CRLF) - 1); |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
873 |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
874 while (m > p) { |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
875 if (m[0] == CR && m[1] == LF) { |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
876 break; |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
877 } |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
878 |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
879 m--; |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
880 } |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
881 |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
882 if (m <= p || m[5] == '-') { |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
883 return NGX_AGAIN; |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
884 } |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
885 } |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
886 |
1136 | 887 switch (state) { |
888 | |
2311
6bad42a41dd8
do not close session if SMTP backend returned an error on RCPT TO
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
889 case ngx_smtp_start: |
6bad42a41dd8
do not close session if SMTP backend returned an error on RCPT TO
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
890 if (p[0] == '2' && p[1] == '2' && p[2] == '0') { |
1166 | 891 return NGX_OK; |
892 } | |
893 break; | |
1136 | 894 |
2311
6bad42a41dd8
do not close session if SMTP backend returned an error on RCPT TO
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
895 case ngx_smtp_helo: |
6bad42a41dd8
do not close session if SMTP backend returned an error on RCPT TO
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
896 case ngx_smtp_helo_xclient: |
6bad42a41dd8
do not close session if SMTP backend returned an error on RCPT TO
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
897 case ngx_smtp_helo_from: |
8178
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
898 case ngx_smtp_helo_auth: |
2311
6bad42a41dd8
do not close session if SMTP backend returned an error on RCPT TO
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
899 case ngx_smtp_from: |
6bad42a41dd8
do not close session if SMTP backend returned an error on RCPT TO
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
900 if (p[0] == '2' && p[1] == '5' && p[2] == '0') { |
2309 | 901 return NGX_OK; |
902 } | |
903 break; | |
904 | |
1136 | 905 case ngx_smtp_xclient: |
2309 | 906 case ngx_smtp_xclient_from: |
2497 | 907 case ngx_smtp_xclient_helo: |
8178
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
908 case ngx_smtp_xclient_auth: |
2309 | 909 if (p[0] == '2' && (p[1] == '2' || p[1] == '5') && p[2] == '0') { |
1166 | 910 return NGX_OK; |
911 } | |
912 break; | |
2311
6bad42a41dd8
do not close session if SMTP backend returned an error on RCPT TO
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
913 |
8178
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
914 case ngx_smtp_auth_plain: |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
915 if (p[0] == '2' && p[1] == '3' && p[2] == '5') { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
916 return NGX_OK; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
917 } |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
918 break; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
919 |
2311
6bad42a41dd8
do not close session if SMTP backend returned an error on RCPT TO
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
920 case ngx_smtp_to: |
6bad42a41dd8
do not close session if SMTP backend returned an error on RCPT TO
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
921 return NGX_OK; |
1136 | 922 } |
923 | |
1166 | 924 break; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
925 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
926 |
1136 | 927 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); |
857 | 928 |
929 if (pcf->pass_error_message == 0) { | |
930 *(b->last - 2) = '\0'; | |
931 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, | |
932 "upstream sent invalid response: \"%s\"", p); | |
933 return NGX_ERROR; | |
934 } | |
935 | |
936 s->out.len = b->last - p - 2; | |
937 s->out.data = p; | |
938 | |
939 ngx_log_error(NGX_LOG_INFO, s->connection->log, 0, | |
940 "upstream sent invalid response: \"%V\"", &s->out); | |
941 | |
942 s->out.len = b->last - b->pos; | |
943 s->out.data = b->pos; | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
944 |
571 | 945 return NGX_ERROR; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
946 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
947 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
948 |
521 | 949 static void |
1136 | 950 ngx_mail_proxy_handler(ngx_event_t *ev) |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
951 { |
583 | 952 char *action, *recv_action, *send_action; |
539 | 953 size_t size; |
954 ssize_t n; | |
955 ngx_buf_t *b; | |
583 | 956 ngx_uint_t do_write; |
539 | 957 ngx_connection_t *c, *src, *dst; |
1136 | 958 ngx_mail_session_t *s; |
959 ngx_mail_proxy_conf_t *pcf; | |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
960 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
961 c = ev->data; |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
962 s = c->data; |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
963 |
7156
9c29644f6d03
Fixed worker_shutdown_timeout in various cases.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6480
diff
changeset
|
964 if (ev->timedout || c->close) { |
583 | 965 c->log->action = "proxying"; |
966 | |
7156
9c29644f6d03
Fixed worker_shutdown_timeout in various cases.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6480
diff
changeset
|
967 if (c->close) { |
9c29644f6d03
Fixed worker_shutdown_timeout in various cases.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6480
diff
changeset
|
968 ngx_log_error(NGX_LOG_INFO, c->log, 0, "shutdown timeout"); |
9c29644f6d03
Fixed worker_shutdown_timeout in various cases.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6480
diff
changeset
|
969 |
9c29644f6d03
Fixed worker_shutdown_timeout in various cases.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6480
diff
changeset
|
970 } else if (c == s->connection) { |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
971 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
972 "client timed out"); |
577 | 973 c->timedout = 1; |
974 | |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
975 } else { |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
976 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
977 "upstream timed out"); |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
978 } |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
979 |
1136 | 980 ngx_mail_proxy_close_session(s); |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
981 return; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
982 } |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
983 |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
984 if (c == s->connection) { |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
985 if (ev->write) { |
583 | 986 recv_action = "proxying and reading from upstream"; |
987 send_action = "proxying and sending to client"; | |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
988 src = s->proxy->upstream.connection; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
989 dst = c; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
990 b = s->proxy->buffer; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
991 |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
992 } else { |
583 | 993 recv_action = "proxying and reading from client"; |
994 send_action = "proxying and sending to upstream"; | |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
995 src = c; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
996 dst = s->proxy->upstream.connection; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
997 b = s->buffer; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
998 } |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
999 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1000 } else { |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1001 if (ev->write) { |
589 | 1002 recv_action = "proxying and reading from client"; |
1003 send_action = "proxying and sending to upstream"; | |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1004 src = s->connection; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1005 dst = c; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1006 b = s->buffer; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1007 |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1008 } else { |
589 | 1009 recv_action = "proxying and reading from upstream"; |
1010 send_action = "proxying and sending to client"; | |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1011 src = c; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1012 dst = s->connection; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1013 b = s->proxy->buffer; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1014 } |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1015 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1016 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1017 do_write = ev->write ? 1 : 0; |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1018 |
1136 | 1019 ngx_log_debug3(NGX_LOG_DEBUG_MAIL, ev->log, 0, |
6480 | 1020 "mail proxy handler: %ui, #%d > #%d", |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
1021 do_write, src->fd, dst->fd); |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
1022 |
583 | 1023 for ( ;; ) { |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1024 |
583 | 1025 if (do_write) { |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
1026 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
1027 size = b->last - b->pos; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
1028 |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1029 if (size && dst->write->ready) { |
583 | 1030 c->log->action = send_action; |
1031 | |
539 | 1032 n = dst->send(dst, b->pos, size); |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1033 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1034 if (n == NGX_ERROR) { |
1136 | 1035 ngx_mail_proxy_close_session(s); |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1036 return; |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1037 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1038 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1039 if (n > 0) { |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1040 b->pos += n; |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1041 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1042 if (b->pos == b->last) { |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1043 b->pos = b->start; |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1044 b->last = b->start; |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1045 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1046 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1047 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1048 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1049 |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
1050 size = b->end - b->last; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
1051 |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1052 if (size && src->read->ready) { |
583 | 1053 c->log->action = recv_action; |
1054 | |
539 | 1055 n = src->recv(src, b->last, size); |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1056 |
583 | 1057 if (n == NGX_AGAIN || n == 0) { |
1058 break; | |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1059 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1060 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1061 if (n > 0) { |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1062 do_write = 1; |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1063 b->last += n; |
583 | 1064 |
1065 continue; | |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1066 } |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
1067 |
583 | 1068 if (n == NGX_ERROR) { |
1069 src->read->eof = 1; | |
539 | 1070 } |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1071 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1072 |
583 | 1073 break; |
1074 } | |
1075 | |
1076 c->log->action = "proxying"; | |
1077 | |
1342
be2e13691c60
fix case when client has closed connection but upstream buffer is not empty
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
1078 if ((s->connection->read->eof && s->buffer->pos == s->buffer->last) |
be2e13691c60
fix case when client has closed connection but upstream buffer is not empty
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
1079 || (s->proxy->upstream.connection->read->eof |
be2e13691c60
fix case when client has closed connection but upstream buffer is not empty
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
1080 && s->proxy->buffer->pos == s->proxy->buffer->last) |
be2e13691c60
fix case when client has closed connection but upstream buffer is not empty
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
1081 || (s->connection->read->eof |
be2e13691c60
fix case when client has closed connection but upstream buffer is not empty
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
1082 && s->proxy->upstream.connection->read->eof)) |
583 | 1083 { |
1084 action = c->log->action; | |
1085 c->log->action = NULL; | |
1086 ngx_log_error(NGX_LOG_INFO, c->log, 0, "proxied session done"); | |
1087 c->log->action = action; | |
1088 | |
1136 | 1089 ngx_mail_proxy_close_session(s); |
583 | 1090 return; |
1091 } | |
1092 | |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2311
diff
changeset
|
1093 if (ngx_handle_write_event(dst->write, 0) != NGX_OK) { |
1136 | 1094 ngx_mail_proxy_close_session(s); |
583 | 1095 return; |
1096 } | |
1097 | |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2311
diff
changeset
|
1098 if (ngx_handle_read_event(dst->read, 0) != NGX_OK) { |
1136 | 1099 ngx_mail_proxy_close_session(s); |
583 | 1100 return; |
1101 } | |
1102 | |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2311
diff
changeset
|
1103 if (ngx_handle_write_event(src->write, 0) != NGX_OK) { |
1136 | 1104 ngx_mail_proxy_close_session(s); |
583 | 1105 return; |
1106 } | |
1107 | |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2311
diff
changeset
|
1108 if (ngx_handle_read_event(src->read, 0) != NGX_OK) { |
1136 | 1109 ngx_mail_proxy_close_session(s); |
583 | 1110 return; |
1111 } | |
1112 | |
1113 if (c == s->connection) { | |
1136 | 1114 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); |
583 | 1115 ngx_add_timer(c->read, pcf->timeout); |
1116 } | |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1117 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1118 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1119 |
521 | 1120 static void |
1136 | 1121 ngx_mail_proxy_upstream_error(ngx_mail_session_t *s) |
857 | 1122 { |
1123 if (s->proxy->upstream.connection) { | |
1136 | 1124 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, |
1125 "close mail proxy connection: %d", | |
857 | 1126 s->proxy->upstream.connection->fd); |
1127 | |
1128 ngx_close_connection(s->proxy->upstream.connection); | |
1129 } | |
1130 | |
1131 if (s->out.len == 0) { | |
1136 | 1132 ngx_mail_session_internal_server_error(s); |
857 | 1133 return; |
1134 } | |
1135 | |
1136 s->quit = 1; | |
1136 | 1137 ngx_mail_send(s->connection->write); |
857 | 1138 } |
1139 | |
1140 | |
1141 static void | |
1136 | 1142 ngx_mail_proxy_internal_server_error(ngx_mail_session_t *s) |
527 | 1143 { |
1144 if (s->proxy->upstream.connection) { | |
1136 | 1145 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, |
1146 "close mail proxy connection: %d", | |
527 | 1147 s->proxy->upstream.connection->fd); |
1148 | |
1149 ngx_close_connection(s->proxy->upstream.connection); | |
1150 } | |
1151 | |
1136 | 1152 ngx_mail_session_internal_server_error(s); |
527 | 1153 } |
1154 | |
1155 | |
1156 static void | |
1136 | 1157 ngx_mail_proxy_close_session(ngx_mail_session_t *s) |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1158 { |
521 | 1159 if (s->proxy->upstream.connection) { |
1136 | 1160 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, |
1161 "close mail proxy connection: %d", | |
521 | 1162 s->proxy->upstream.connection->fd); |
1163 | |
1164 ngx_close_connection(s->proxy->upstream.connection); | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
1165 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
1166 |
1136 | 1167 ngx_mail_close_connection(s->connection); |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1168 } |
521 | 1169 |
1170 | |
1171 static void * | |
1136 | 1172 ngx_mail_proxy_create_conf(ngx_conf_t *cf) |
577 | 1173 { |
1136 | 1174 ngx_mail_proxy_conf_t *pcf; |
577 | 1175 |
1136 | 1176 pcf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_proxy_conf_t)); |
521 | 1177 if (pcf == NULL) { |
2912
c7d57b539248
return NULL instead of NGX_CONF_ERROR on a create conf failure
Igor Sysoev <igor@sysoev.ru>
parents:
2497
diff
changeset
|
1178 return NULL; |
521 | 1179 } |
1180 | |
1181 pcf->enable = NGX_CONF_UNSET; | |
857 | 1182 pcf->pass_error_message = NGX_CONF_UNSET; |
1136 | 1183 pcf->xclient = NGX_CONF_UNSET; |
8178
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
1184 pcf->smtp_auth = NGX_CONF_UNSET; |
539 | 1185 pcf->buffer_size = NGX_CONF_UNSET_SIZE; |
1186 pcf->timeout = NGX_CONF_UNSET_MSEC; | |
521 | 1187 |
1188 return pcf; | |
1189 } | |
1190 | |
1191 | |
1192 static char * | |
1136 | 1193 ngx_mail_proxy_merge_conf(ngx_conf_t *cf, void *parent, void *child) |
521 | 1194 { |
1136 | 1195 ngx_mail_proxy_conf_t *prev = parent; |
1196 ngx_mail_proxy_conf_t *conf = child; | |
521 | 1197 |
539 | 1198 ngx_conf_merge_value(conf->enable, prev->enable, 0); |
857 | 1199 ngx_conf_merge_value(conf->pass_error_message, prev->pass_error_message, 0); |
1136 | 1200 ngx_conf_merge_value(conf->xclient, prev->xclient, 1); |
8178
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
1201 ngx_conf_merge_value(conf->smtp_auth, prev->smtp_auth, 0); |
539 | 1202 ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, |
1203 (size_t) ngx_pagesize); | |
1204 ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 24 * 60 * 60000); | |
521 | 1205 |
1206 return NGX_CONF_OK; | |
1207 } |