Mercurial > hg > nginx
annotate src/mail/ngx_mail_proxy_module.c @ 7794:12ea1de7d87c
Mail: parsing of the PROXY protocol from clients.
Activated with the "proxy_protocol" parameter of the "listen" directive.
Obtained information is passed to the auth_http script in Proxy-Protocol-Addr,
Proxy-Protocol-Port, Proxy-Protocol-Server-Addr, and Proxy-Protocol-Server-Port
headers.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Fri, 05 Mar 2021 17:16:24 +0300 |
parents | da0a85e91587 |
children | 4b8f23a36ebf |
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; |
7725
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 | |
7725
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) { |
7790
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
236 if (ngx_handle_read_event(c->read, 0) != NGX_OK) { |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
237 ngx_mail_proxy_internal_server_error(s); |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
238 return; |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
239 } |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
240 |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
241 return; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
242 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
243 |
571 | 244 if (rc == NGX_ERROR) { |
1136 | 245 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
|
246 return; |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
247 } |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
248 |
1136 | 249 switch (s->mail_state) { |
587 | 250 |
1136 | 251 case ngx_pop3_start: |
252 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
|
253 |
587 | 254 s->connection->log->action = "sending user name to upstream"; |
255 | |
1136 | 256 line.len = sizeof("USER ") - 1 + s->login.len + 2; |
2049 | 257 line.data = ngx_pnalloc(c->pool, line.len); |
527 | 258 if (line.data == NULL) { |
1136 | 259 ngx_mail_proxy_internal_server_error(s); |
527 | 260 return; |
261 } | |
262 | |
1136 | 263 p = ngx_cpymem(line.data, "USER ", sizeof("USER ") - 1); |
264 p = ngx_cpymem(p, s->login.data, s->login.len); | |
265 *p++ = CR; *p = LF; | |
527 | 266 |
1136 | 267 s->mail_state = ngx_pop3_user; |
527 | 268 break; |
269 | |
1136 | 270 case ngx_pop3_user: |
271 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail proxy send pass"); | |
527 | 272 |
587 | 273 s->connection->log->action = "sending password to upstream"; |
274 | |
1136 | 275 line.len = sizeof("PASS ") - 1 + s->passwd.len + 2; |
2049 | 276 line.data = ngx_pnalloc(c->pool, line.len); |
501 | 277 if (line.data == NULL) { |
1136 | 278 ngx_mail_proxy_internal_server_error(s); |
527 | 279 return; |
280 } | |
281 | |
1136 | 282 p = ngx_cpymem(line.data, "PASS ", sizeof("PASS ") - 1); |
283 p = ngx_cpymem(p, s->passwd.data, s->passwd.len); | |
527 | 284 *p++ = CR; *p = LF; |
285 | |
1136 | 286 s->mail_state = ngx_pop3_passwd; |
527 | 287 break; |
288 | |
1136 | 289 case ngx_pop3_passwd: |
290 s->connection->read->handler = ngx_mail_proxy_handler; | |
291 s->connection->write->handler = ngx_mail_proxy_handler; | |
292 rev->handler = ngx_mail_proxy_handler; | |
293 c->write->handler = ngx_mail_proxy_handler; | |
663 | 294 |
1136 | 295 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); |
663 | 296 ngx_add_timer(s->connection->read, pcf->timeout); |
297 ngx_del_timer(c->read); | |
298 | |
299 c->log->action = NULL; | |
300 ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in"); | |
301 | |
1136 | 302 ngx_mail_proxy_handler(s->connection->write); |
663 | 303 |
304 return; | |
305 | |
527 | 306 default: |
307 #if (NGX_SUPPRESS_WARN) | |
3516
dd1570b6f237
ngx_str_set() and ngx_str_null()
Igor Sysoev <igor@sysoev.ru>
parents:
3505
diff
changeset
|
308 ngx_str_null(&line); |
527 | 309 #endif |
310 break; | |
311 } | |
312 | |
539 | 313 if (c->send(c, line.data, line.len) < (ssize_t) line.len) { |
527 | 314 /* |
315 * we treat the incomplete sending as NGX_ERROR | |
316 * because it is very strange here | |
317 */ | |
1136 | 318 ngx_mail_proxy_internal_server_error(s); |
527 | 319 return; |
320 } | |
321 | |
7790
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
322 if (ngx_handle_read_event(c->read, 0) != NGX_OK) { |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
323 ngx_mail_proxy_internal_server_error(s); |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
324 return; |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
325 } |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
326 |
527 | 327 s->proxy->buffer->pos = s->proxy->buffer->start; |
328 s->proxy->buffer->last = s->proxy->buffer->start; | |
329 } | |
330 | |
331 | |
332 static void | |
1136 | 333 ngx_mail_proxy_imap_handler(ngx_event_t *rev) |
527 | 334 { |
539 | 335 u_char *p; |
336 ngx_int_t rc; | |
337 ngx_str_t line; | |
338 ngx_connection_t *c; | |
1136 | 339 ngx_mail_session_t *s; |
340 ngx_mail_proxy_conf_t *pcf; | |
527 | 341 |
1136 | 342 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, |
343 "mail proxy imap auth handler"); | |
527 | 344 |
345 c = rev->data; | |
346 s = c->data; | |
347 | |
348 if (rev->timedout) { | |
349 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, | |
350 "upstream timed out"); | |
577 | 351 c->timedout = 1; |
1136 | 352 ngx_mail_proxy_internal_server_error(s); |
527 | 353 return; |
354 } | |
355 | |
1136 | 356 rc = ngx_mail_proxy_read_response(s, s->mail_state); |
527 | 357 |
358 if (rc == NGX_AGAIN) { | |
7790
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
359 if (ngx_handle_read_event(c->read, 0) != NGX_OK) { |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
360 ngx_mail_proxy_internal_server_error(s); |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
361 return; |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
362 } |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
363 |
527 | 364 return; |
365 } | |
366 | |
571 | 367 if (rc == NGX_ERROR) { |
1136 | 368 ngx_mail_proxy_upstream_error(s); |
527 | 369 return; |
370 } | |
371 | |
1136 | 372 switch (s->mail_state) { |
527 | 373 |
1136 | 374 case ngx_imap_start: |
375 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, | |
376 "mail proxy send login"); | |
527 | 377 |
1136 | 378 s->connection->log->action = "sending LOGIN command to upstream"; |
587 | 379 |
1136 | 380 line.len = s->tag.len + sizeof("LOGIN ") - 1 |
381 + 1 + NGX_SIZE_T_LEN + 1 + 2; | |
2049 | 382 line.data = ngx_pnalloc(c->pool, line.len); |
527 | 383 if (line.data == NULL) { |
1136 | 384 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
|
385 return; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
386 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
387 |
1136 | 388 line.len = ngx_sprintf(line.data, "%VLOGIN {%uz}" CRLF, |
389 &s->tag, s->login.len) | |
390 - line.data; | |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
391 |
1136 | 392 s->mail_state = ngx_imap_login; |
527 | 393 break; |
394 | |
1136 | 395 case ngx_imap_login: |
396 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail proxy send user"); | |
397 | |
398 s->connection->log->action = "sending user name to upstream"; | |
399 | |
400 line.len = s->login.len + 1 + 1 + NGX_SIZE_T_LEN + 1 + 2; | |
2049 | 401 line.data = ngx_pnalloc(c->pool, line.len); |
1136 | 402 if (line.data == NULL) { |
403 ngx_mail_proxy_internal_server_error(s); | |
404 return; | |
405 } | |
406 | |
407 line.len = ngx_sprintf(line.data, "%V {%uz}" CRLF, | |
408 &s->login, s->passwd.len) | |
409 - line.data; | |
410 | |
411 s->mail_state = ngx_imap_user; | |
412 break; | |
413 | |
414 case ngx_imap_user: | |
415 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, | |
416 "mail proxy send passwd"); | |
527 | 417 |
587 | 418 s->connection->log->action = "sending password to upstream"; |
419 | |
1136 | 420 line.len = s->passwd.len + 2; |
2049 | 421 line.data = ngx_pnalloc(c->pool, line.len); |
527 | 422 if (line.data == NULL) { |
1136 | 423 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
|
424 return; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
425 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
426 |
1136 | 427 p = ngx_cpymem(line.data, s->passwd.data, s->passwd.len); |
527 | 428 *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
|
429 |
1136 | 430 s->mail_state = ngx_imap_passwd; |
527 | 431 break; |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
432 |
1136 | 433 case ngx_imap_passwd: |
434 s->connection->read->handler = ngx_mail_proxy_handler; | |
435 s->connection->write->handler = ngx_mail_proxy_handler; | |
436 rev->handler = ngx_mail_proxy_handler; | |
437 c->write->handler = ngx_mail_proxy_handler; | |
663 | 438 |
1136 | 439 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); |
663 | 440 ngx_add_timer(s->connection->read, pcf->timeout); |
441 ngx_del_timer(c->read); | |
442 | |
443 c->log->action = NULL; | |
444 ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in"); | |
445 | |
1136 | 446 ngx_mail_proxy_handler(s->connection->write); |
663 | 447 |
448 return; | |
449 | |
527 | 450 default: |
451 #if (NGX_SUPPRESS_WARN) | |
3516
dd1570b6f237
ngx_str_set() and ngx_str_null()
Igor Sysoev <igor@sysoev.ru>
parents:
3505
diff
changeset
|
452 ngx_str_null(&line); |
527 | 453 #endif |
454 break; | |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
455 } |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
456 |
539 | 457 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
|
458 /* |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
459 * 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
|
460 * 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
|
461 */ |
1136 | 462 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
|
463 return; |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
464 } |
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
465 |
7790
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
466 if (ngx_handle_read_event(c->read, 0) != NGX_OK) { |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
467 ngx_mail_proxy_internal_server_error(s); |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
468 return; |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
469 } |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
470 |
422
edaefb2a20fc
nginx-0.0.10-2004-09-12-00:22:11 import
Igor Sysoev <igor@sysoev.ru>
parents:
419
diff
changeset
|
471 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
|
472 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
|
473 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
474 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
475 |
521 | 476 static void |
1136 | 477 ngx_mail_proxy_smtp_handler(ngx_event_t *rev) |
478 { | |
479 u_char *p; | |
480 ngx_int_t rc; | |
7725
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
481 ngx_str_t line, auth, encoded; |
2309 | 482 ngx_buf_t *b; |
1136 | 483 ngx_connection_t *c; |
484 ngx_mail_session_t *s; | |
485 ngx_mail_proxy_conf_t *pcf; | |
486 ngx_mail_core_srv_conf_t *cscf; | |
487 | |
488 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, | |
489 "mail proxy smtp auth handler"); | |
490 | |
491 c = rev->data; | |
492 s = c->data; | |
493 | |
494 if (rev->timedout) { | |
495 ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, | |
496 "upstream timed out"); | |
497 c->timedout = 1; | |
498 ngx_mail_proxy_internal_server_error(s); | |
499 return; | |
500 } | |
501 | |
502 rc = ngx_mail_proxy_read_response(s, s->mail_state); | |
503 | |
504 if (rc == NGX_AGAIN) { | |
7790
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
505 if (ngx_handle_read_event(c->read, 0) != NGX_OK) { |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
506 ngx_mail_proxy_internal_server_error(s); |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
507 return; |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
508 } |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
509 |
1136 | 510 return; |
511 } | |
512 | |
513 if (rc == NGX_ERROR) { | |
514 ngx_mail_proxy_upstream_error(s); | |
515 return; | |
516 } | |
517 | |
518 switch (s->mail_state) { | |
519 | |
520 case ngx_smtp_start: | |
521 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail proxy send ehlo"); | |
522 | |
523 s->connection->log->action = "sending HELO/EHLO to upstream"; | |
524 | |
525 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); | |
526 | |
527 line.len = sizeof("HELO ") - 1 + cscf->server_name.len + 2; | |
2049 | 528 line.data = ngx_pnalloc(c->pool, line.len); |
1136 | 529 if (line.data == NULL) { |
530 ngx_mail_proxy_internal_server_error(s); | |
531 return; | |
532 } | |
533 | |
534 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); | |
535 | |
536 p = ngx_cpymem(line.data, | |
537 ((s->esmtp || pcf->xclient) ? "EHLO " : "HELO "), | |
538 sizeof("HELO ") - 1); | |
539 | |
540 p = ngx_cpymem(p, cscf->server_name.data, cscf->server_name.len); | |
541 *p++ = CR; *p = LF; | |
542 | |
2309 | 543 if (pcf->xclient) { |
544 s->mail_state = ngx_smtp_helo_xclient; | |
545 | |
546 } else if (s->auth_method == NGX_MAIL_AUTH_NONE) { | |
547 s->mail_state = ngx_smtp_helo_from; | |
548 | |
7725
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
549 } else if (pcf->smtp_auth) { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
550 s->mail_state = ngx_smtp_helo_auth; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
551 |
2309 | 552 } else { |
553 s->mail_state = ngx_smtp_helo; | |
554 } | |
1136 | 555 |
556 break; | |
557 | |
2309 | 558 case ngx_smtp_helo_xclient: |
1136 | 559 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, |
560 "mail proxy send xclient"); | |
561 | |
562 s->connection->log->action = "sending XCLIENT to upstream"; | |
563 | |
2497 | 564 line.len = sizeof("XCLIENT ADDR= LOGIN= NAME=" |
1892
057d362ee50e
resolver in smtp proxy module
Igor Sysoev <igor@sysoev.ru>
parents:
1487
diff
changeset
|
565 CRLF) - 1 |
057d362ee50e
resolver in smtp proxy module
Igor Sysoev <igor@sysoev.ru>
parents:
1487
diff
changeset
|
566 + s->connection->addr_text.len + s->login.len + s->host.len; |
1136 | 567 |
5522
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
568 #if (NGX_HAVE_INET6) |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
569 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
|
570 line.len += sizeof("IPV6:") - 1; |
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 #endif |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
573 |
2049 | 574 line.data = ngx_pnalloc(c->pool, line.len); |
1136 | 575 if (line.data == NULL) { |
576 ngx_mail_proxy_internal_server_error(s); | |
577 return; | |
578 } | |
579 | |
5522
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
580 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
|
581 |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
582 #if (NGX_HAVE_INET6) |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
583 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
|
584 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
|
585 } |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
586 #endif |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
587 |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
588 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
|
589 s->connection->addr_text.len); |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
590 |
7725
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
591 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
|
592 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
593 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
|
594 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
|
595 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
|
596 } |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
597 |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
598 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
|
599 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
|
600 |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
601 *p++ = CR; *p++ = LF; |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
602 |
bb3dc21c89ef
Mail: fixed passing of IPv6 client address in XCLIENT.
Ruslan Ermilov <ru@nginx.com>
parents:
5399
diff
changeset
|
603 line.len = p - line.data; |
2309 | 604 |
2497 | 605 if (s->smtp_helo.len) { |
606 s->mail_state = ngx_smtp_xclient_helo; | |
607 | |
608 } else if (s->auth_method == NGX_MAIL_AUTH_NONE) { | |
609 s->mail_state = ngx_smtp_xclient_from; | |
610 | |
7725
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
611 } else if (pcf->smtp_auth) { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
612 s->mail_state = ngx_smtp_xclient_auth; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
613 |
2497 | 614 } else { |
615 s->mail_state = ngx_smtp_xclient; | |
616 } | |
617 | |
618 break; | |
619 | |
620 case ngx_smtp_xclient_helo: | |
621 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, | |
622 "mail proxy send client ehlo"); | |
623 | |
624 s->connection->log->action = "sending client HELO/EHLO to upstream"; | |
625 | |
626 line.len = sizeof("HELO " CRLF) - 1 + s->smtp_helo.len; | |
627 | |
628 line.data = ngx_pnalloc(c->pool, line.len); | |
629 if (line.data == NULL) { | |
630 ngx_mail_proxy_internal_server_error(s); | |
631 return; | |
632 } | |
633 | |
634 line.len = ngx_sprintf(line.data, | |
635 ((s->esmtp) ? "EHLO %V" CRLF : "HELO %V" CRLF), | |
636 &s->smtp_helo) | |
637 - line.data; | |
638 | |
7725
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
639 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
|
640 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
641 if (s->auth_method == NGX_MAIL_AUTH_NONE) { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
642 s->mail_state = ngx_smtp_helo_from; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
643 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
644 } else if (pcf->smtp_auth) { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
645 s->mail_state = ngx_smtp_helo_auth; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
646 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
647 } else { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
648 s->mail_state = ngx_smtp_helo; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
649 } |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
650 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
651 break; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
652 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
653 case ngx_smtp_helo_auth: |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
654 case ngx_smtp_xclient_auth: |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
655 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
|
656 "mail proxy send auth"); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
657 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
658 s->connection->log->action = "sending AUTH to upstream"; |
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 if (s->passwd.data == NULL) { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
661 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
|
662 "no password available"); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
663 ngx_mail_proxy_internal_server_error(s); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
664 return; |
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 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
667 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
|
668 auth.data = ngx_pnalloc(c->pool, auth.len); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
669 if (auth.data == NULL) { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
670 ngx_mail_proxy_internal_server_error(s); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
671 return; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
672 } |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
673 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
674 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
|
675 - auth.data; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
676 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
677 line.len = sizeof("AUTH PLAIN " CRLF) - 1 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
678 + ngx_base64_encoded_length(auth.len); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
679 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
680 line.data = ngx_pnalloc(c->pool, line.len); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
681 if (line.data == NULL) { |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
682 ngx_mail_proxy_internal_server_error(s); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
683 return; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
684 } |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
685 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
686 encoded.data = ngx_cpymem(line.data, "AUTH PLAIN ", |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
687 sizeof("AUTH PLAIN ") - 1); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
688 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
689 ngx_encode_base64(&encoded, &auth); |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
690 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
691 p = encoded.data + encoded.len; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
692 *p++ = CR; *p = LF; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
693 |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
694 s->mail_state = ngx_smtp_auth_plain; |
2309 | 695 |
696 break; | |
697 | |
698 case ngx_smtp_helo_from: | |
699 case ngx_smtp_xclient_from: | |
700 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, | |
701 "mail proxy send mail from"); | |
702 | |
703 s->connection->log->action = "sending MAIL FROM to upstream"; | |
704 | |
705 line.len = s->smtp_from.len + sizeof(CRLF) - 1; | |
706 line.data = ngx_pnalloc(c->pool, line.len); | |
707 if (line.data == NULL) { | |
708 ngx_mail_proxy_internal_server_error(s); | |
709 return; | |
1136 | 710 } |
711 | |
2309 | 712 p = ngx_cpymem(line.data, s->smtp_from.data, s->smtp_from.len); |
713 *p++ = CR; *p = LF; | |
714 | |
715 s->mail_state = ngx_smtp_from; | |
716 | |
1136 | 717 break; |
718 | |
2309 | 719 case ngx_smtp_from: |
720 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, | |
721 "mail proxy send rcpt to"); | |
722 | |
723 s->connection->log->action = "sending RCPT TO to upstream"; | |
724 | |
725 line.len = s->smtp_to.len + sizeof(CRLF) - 1; | |
726 line.data = ngx_pnalloc(c->pool, line.len); | |
727 if (line.data == NULL) { | |
728 ngx_mail_proxy_internal_server_error(s); | |
729 return; | |
730 } | |
731 | |
732 p = ngx_cpymem(line.data, s->smtp_to.data, s->smtp_to.len); | |
733 *p++ = CR; *p = LF; | |
734 | |
735 s->mail_state = ngx_smtp_to; | |
1136 | 736 |
2309 | 737 break; |
738 | |
739 case ngx_smtp_helo: | |
740 case ngx_smtp_xclient: | |
7725
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
741 case ngx_smtp_auth_plain: |
2309 | 742 case ngx_smtp_to: |
743 | |
744 b = s->proxy->buffer; | |
1136 | 745 |
2309 | 746 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
|
747 b->pos = b->start; |
2309 | 748 |
749 } else { | |
2440
939b40aa9ab4
update r2439: make clear name
Igor Sysoev <igor@sysoev.ru>
parents:
2438
diff
changeset
|
750 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
|
751 b->last = b->start + sizeof(smtp_auth_ok) - 1; |
2309 | 752 } |
753 | |
1136 | 754 s->connection->read->handler = ngx_mail_proxy_handler; |
755 s->connection->write->handler = ngx_mail_proxy_handler; | |
756 rev->handler = ngx_mail_proxy_handler; | |
757 c->write->handler = ngx_mail_proxy_handler; | |
758 | |
759 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); | |
760 ngx_add_timer(s->connection->read, pcf->timeout); | |
761 ngx_del_timer(c->read); | |
762 | |
763 c->log->action = NULL; | |
764 ngx_log_error(NGX_LOG_INFO, c->log, 0, "client logged in"); | |
765 | |
5398
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
766 if (s->buffer->pos == s->buffer->last) { |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
767 ngx_mail_proxy_handler(s->connection->write); |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
768 |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
769 } else { |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
770 ngx_mail_proxy_handler(c->write); |
04e43d03e153
Mail: smtp pipelining support.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
771 } |
1136 | 772 |
773 return; | |
774 | |
775 default: | |
776 #if (NGX_SUPPRESS_WARN) | |
3516
dd1570b6f237
ngx_str_set() and ngx_str_null()
Igor Sysoev <igor@sysoev.ru>
parents:
3505
diff
changeset
|
777 ngx_str_null(&line); |
1136 | 778 #endif |
779 break; | |
780 } | |
781 | |
782 if (c->send(c, line.data, line.len) < (ssize_t) line.len) { | |
783 /* | |
784 * we treat the incomplete sending as NGX_ERROR | |
785 * because it is very strange here | |
786 */ | |
787 ngx_mail_proxy_internal_server_error(s); | |
788 return; | |
789 } | |
790 | |
7790
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
791 if (ngx_handle_read_event(c->read, 0) != NGX_OK) { |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
792 ngx_mail_proxy_internal_server_error(s); |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
793 return; |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
794 } |
da0a85e91587
Mail: added missing event handling after reading data.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7725
diff
changeset
|
795 |
1136 | 796 s->proxy->buffer->pos = s->proxy->buffer->start; |
797 s->proxy->buffer->last = s->proxy->buffer->start; | |
798 } | |
799 | |
800 | |
801 static void | |
802 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
|
803 { |
583 | 804 ngx_connection_t *c; |
1136 | 805 ngx_mail_session_t *s; |
583 | 806 |
1136 | 807 ngx_log_debug0(NGX_LOG_DEBUG_MAIL, wev->log, 0, "mail proxy dummy handler"); |
583 | 808 |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2311
diff
changeset
|
809 if (ngx_handle_write_event(wev, 0) != NGX_OK) { |
583 | 810 c = wev->data; |
811 s = c->data; | |
812 | |
1136 | 813 ngx_mail_proxy_close_session(s); |
583 | 814 } |
419
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 |
521 | 818 static ngx_int_t |
1136 | 819 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
|
820 { |
5399
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
821 u_char *p, *m; |
857 | 822 ssize_t n; |
823 ngx_buf_t *b; | |
1136 | 824 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
|
825 |
587 | 826 s->connection->log->action = "reading response from upstream"; |
827 | |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
828 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
|
829 |
539 | 830 n = s->proxy->upstream.connection->recv(s->proxy->upstream.connection, |
831 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
|
832 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
833 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
|
834 return NGX_ERROR; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
835 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
836 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
837 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
|
838 return NGX_AGAIN; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
839 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
840 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
841 b->last += n; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
842 |
3505
c631ef8beaaa
Zimbra IMAP server may return only 4 bytes: "+ \r\n"
Igor Sysoev <igor@sysoev.ru>
parents:
3269
diff
changeset
|
843 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
|
844 return NGX_AGAIN; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
845 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
846 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
847 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
|
848 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
|
849 *(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
|
850 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
|
851 "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
|
852 b->pos); |
571 | 853 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
|
854 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
855 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
856 return NGX_AGAIN; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
857 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
858 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
859 p = b->pos; |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
860 |
1136 | 861 switch (s->protocol) { |
862 | |
863 case NGX_MAIL_POP3_PROTOCOL: | |
527 | 864 if (p[0] == '+' && p[1] == 'O' && p[2] == 'K') { |
865 return NGX_OK; | |
866 } | |
1136 | 867 break; |
527 | 868 |
1136 | 869 case NGX_MAIL_IMAP_PROTOCOL: |
663 | 870 switch (state) { |
871 | |
872 case ngx_imap_start: | |
527 | 873 if (p[0] == '*' && p[1] == ' ' && p[2] == 'O' && p[3] == 'K') { |
874 return NGX_OK; | |
875 } | |
663 | 876 break; |
527 | 877 |
663 | 878 case ngx_imap_login: |
879 case ngx_imap_user: | |
529 | 880 if (p[0] == '+') { |
527 | 881 return NGX_OK; |
882 } | |
663 | 883 break; |
884 | |
885 case ngx_imap_passwd: | |
886 if (ngx_strncmp(p, s->tag.data, s->tag.len) == 0) { | |
887 p += s->tag.len; | |
888 if (p[0] == 'O' && p[1] == 'K') { | |
889 return NGX_OK; | |
890 } | |
891 } | |
892 break; | |
527 | 893 } |
1136 | 894 |
895 break; | |
896 | |
897 default: /* NGX_MAIL_SMTP_PROTOCOL */ | |
5399
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
898 |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
899 if (p[3] == '-') { |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
900 /* multiline reply, check if we got last line */ |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
901 |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
902 m = b->last - (sizeof(CRLF "200" CRLF) - 1); |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
903 |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
904 while (m > p) { |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
905 if (m[0] == CR && m[1] == LF) { |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
906 break; |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
907 } |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
908 |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
909 m--; |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
910 } |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
911 |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
912 if (m <= p || m[5] == '-') { |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
913 return NGX_AGAIN; |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
914 } |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
915 } |
d3e09aa03a7a
Mail: handle smtp multiline replies.
Maxim Dounin <mdounin@mdounin.ru>
parents:
5398
diff
changeset
|
916 |
1136 | 917 switch (state) { |
918 | |
2311
6bad42a41dd8
do not close session if SMTP backend returned an error on RCPT TO
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
919 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
|
920 if (p[0] == '2' && p[1] == '2' && p[2] == '0') { |
1166 | 921 return NGX_OK; |
922 } | |
923 break; | |
1136 | 924 |
2311
6bad42a41dd8
do not close session if SMTP backend returned an error on RCPT TO
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
925 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
|
926 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
|
927 case ngx_smtp_helo_from: |
7725
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
928 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
|
929 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
|
930 if (p[0] == '2' && p[1] == '5' && p[2] == '0') { |
2309 | 931 return NGX_OK; |
932 } | |
933 break; | |
934 | |
1136 | 935 case ngx_smtp_xclient: |
2309 | 936 case ngx_smtp_xclient_from: |
2497 | 937 case ngx_smtp_xclient_helo: |
7725
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
938 case ngx_smtp_xclient_auth: |
2309 | 939 if (p[0] == '2' && (p[1] == '2' || p[1] == '5') && p[2] == '0') { |
1166 | 940 return NGX_OK; |
941 } | |
942 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
|
943 |
7725
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
944 case ngx_smtp_auth_plain: |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
945 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
|
946 return NGX_OK; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
947 } |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
948 break; |
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
949 |
2311
6bad42a41dd8
do not close session if SMTP backend returned an error on RCPT TO
Igor Sysoev <igor@sysoev.ru>
parents:
2309
diff
changeset
|
950 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
|
951 return NGX_OK; |
1136 | 952 } |
953 | |
1166 | 954 break; |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
955 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
956 |
1136 | 957 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); |
857 | 958 |
959 if (pcf->pass_error_message == 0) { | |
960 *(b->last - 2) = '\0'; | |
961 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0, | |
962 "upstream sent invalid response: \"%s\"", p); | |
963 return NGX_ERROR; | |
964 } | |
965 | |
966 s->out.len = b->last - p - 2; | |
967 s->out.data = p; | |
968 | |
969 ngx_log_error(NGX_LOG_INFO, s->connection->log, 0, | |
970 "upstream sent invalid response: \"%V\"", &s->out); | |
971 | |
972 s->out.len = b->last - b->pos; | |
973 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
|
974 |
571 | 975 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
|
976 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
977 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
978 |
521 | 979 static void |
1136 | 980 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
|
981 { |
583 | 982 char *action, *recv_action, *send_action; |
539 | 983 size_t size; |
984 ssize_t n; | |
985 ngx_buf_t *b; | |
583 | 986 ngx_uint_t do_write; |
539 | 987 ngx_connection_t *c, *src, *dst; |
1136 | 988 ngx_mail_session_t *s; |
989 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
|
990 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
991 c = ev->data; |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
992 s = c->data; |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
993 |
7156
9c29644f6d03
Fixed worker_shutdown_timeout in various cases.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6480
diff
changeset
|
994 if (ev->timedout || c->close) { |
583 | 995 c->log->action = "proxying"; |
996 | |
7156
9c29644f6d03
Fixed worker_shutdown_timeout in various cases.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6480
diff
changeset
|
997 if (c->close) { |
9c29644f6d03
Fixed worker_shutdown_timeout in various cases.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6480
diff
changeset
|
998 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
|
999 |
9c29644f6d03
Fixed worker_shutdown_timeout in various cases.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6480
diff
changeset
|
1000 } 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
|
1001 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
|
1002 "client timed out"); |
577 | 1003 c->timedout = 1; |
1004 | |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1005 } else { |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1006 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
|
1007 "upstream timed out"); |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1008 } |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1009 |
1136 | 1010 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
|
1011 return; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1012 } |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1013 |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1014 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
|
1015 if (ev->write) { |
583 | 1016 recv_action = "proxying and reading from upstream"; |
1017 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
|
1018 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
|
1019 dst = c; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1020 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
|
1021 |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1022 } else { |
583 | 1023 recv_action = "proxying and reading from client"; |
1024 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
|
1025 src = c; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1026 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
|
1027 b = s->buffer; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1028 } |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1029 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1030 } else { |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1031 if (ev->write) { |
589 | 1032 recv_action = "proxying and reading from client"; |
1033 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
|
1034 src = s->connection; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1035 dst = c; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1036 b = s->buffer; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1037 |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1038 } else { |
589 | 1039 recv_action = "proxying and reading from upstream"; |
1040 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
|
1041 src = c; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1042 dst = s->connection; |
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1043 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
|
1044 } |
418
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 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
|
1048 |
1136 | 1049 ngx_log_debug3(NGX_LOG_DEBUG_MAIL, ev->log, 0, |
6480 | 1050 "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
|
1051 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
|
1052 |
583 | 1053 for ( ;; ) { |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1054 |
583 | 1055 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
|
1056 |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
1057 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
|
1058 |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1059 if (size && dst->write->ready) { |
583 | 1060 c->log->action = send_action; |
1061 | |
539 | 1062 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
|
1063 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1064 if (n == NGX_ERROR) { |
1136 | 1065 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
|
1066 return; |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1067 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1068 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1069 if (n > 0) { |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1070 b->pos += n; |
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 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
|
1073 b->pos = b->start; |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1074 b->last = b->start; |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1075 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1076 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1077 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1078 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1079 |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
1080 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
|
1081 |
423
fda5987b188d
nginx-0.0.10-2004-09-13-20:18:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
422
diff
changeset
|
1082 if (size && src->read->ready) { |
583 | 1083 c->log->action = recv_action; |
1084 | |
539 | 1085 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
|
1086 |
583 | 1087 if (n == NGX_AGAIN || n == 0) { |
1088 break; | |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1089 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1090 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1091 if (n > 0) { |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1092 do_write = 1; |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1093 b->last += n; |
583 | 1094 |
1095 continue; | |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1096 } |
419
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
1097 |
583 | 1098 if (n == NGX_ERROR) { |
1099 src->read->eof = 1; | |
539 | 1100 } |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1101 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1102 |
583 | 1103 break; |
1104 } | |
1105 | |
1106 c->log->action = "proxying"; | |
1107 | |
1342
be2e13691c60
fix case when client has closed connection but upstream buffer is not empty
Igor Sysoev <igor@sysoev.ru>
parents:
1166
diff
changeset
|
1108 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
|
1109 || (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
|
1110 && 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
|
1111 || (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
|
1112 && s->proxy->upstream.connection->read->eof)) |
583 | 1113 { |
1114 action = c->log->action; | |
1115 c->log->action = NULL; | |
1116 ngx_log_error(NGX_LOG_INFO, c->log, 0, "proxied session done"); | |
1117 c->log->action = action; | |
1118 | |
1136 | 1119 ngx_mail_proxy_close_session(s); |
583 | 1120 return; |
1121 } | |
1122 | |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2311
diff
changeset
|
1123 if (ngx_handle_write_event(dst->write, 0) != NGX_OK) { |
1136 | 1124 ngx_mail_proxy_close_session(s); |
583 | 1125 return; |
1126 } | |
1127 | |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2311
diff
changeset
|
1128 if (ngx_handle_read_event(dst->read, 0) != NGX_OK) { |
1136 | 1129 ngx_mail_proxy_close_session(s); |
583 | 1130 return; |
1131 } | |
1132 | |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2311
diff
changeset
|
1133 if (ngx_handle_write_event(src->write, 0) != NGX_OK) { |
1136 | 1134 ngx_mail_proxy_close_session(s); |
583 | 1135 return; |
1136 } | |
1137 | |
2388
722b5aff05ae
use "!= NGX_OK" instead of "== NGX_ERROR"
Igor Sysoev <igor@sysoev.ru>
parents:
2311
diff
changeset
|
1138 if (ngx_handle_read_event(src->read, 0) != NGX_OK) { |
1136 | 1139 ngx_mail_proxy_close_session(s); |
583 | 1140 return; |
1141 } | |
1142 | |
1143 if (c == s->connection) { | |
1136 | 1144 pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); |
583 | 1145 ngx_add_timer(c->read, pcf->timeout); |
1146 } | |
418
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1147 } |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1148 |
cf072d26d6d6
nginx-0.0.10-2004-09-08-09:18:51 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
1149 |
521 | 1150 static void |
1136 | 1151 ngx_mail_proxy_upstream_error(ngx_mail_session_t *s) |
857 | 1152 { |
1153 if (s->proxy->upstream.connection) { | |
1136 | 1154 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, |
1155 "close mail proxy connection: %d", | |
857 | 1156 s->proxy->upstream.connection->fd); |
1157 | |
1158 ngx_close_connection(s->proxy->upstream.connection); | |
1159 } | |
1160 | |
1161 if (s->out.len == 0) { | |
1136 | 1162 ngx_mail_session_internal_server_error(s); |
857 | 1163 return; |
1164 } | |
1165 | |
1166 s->quit = 1; | |
1136 | 1167 ngx_mail_send(s->connection->write); |
857 | 1168 } |
1169 | |
1170 | |
1171 static void | |
1136 | 1172 ngx_mail_proxy_internal_server_error(ngx_mail_session_t *s) |
527 | 1173 { |
1174 if (s->proxy->upstream.connection) { | |
1136 | 1175 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, |
1176 "close mail proxy connection: %d", | |
527 | 1177 s->proxy->upstream.connection->fd); |
1178 | |
1179 ngx_close_connection(s->proxy->upstream.connection); | |
1180 } | |
1181 | |
1136 | 1182 ngx_mail_session_internal_server_error(s); |
527 | 1183 } |
1184 | |
1185 | |
1186 static void | |
1136 | 1187 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
|
1188 { |
521 | 1189 if (s->proxy->upstream.connection) { |
1136 | 1190 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, |
1191 "close mail proxy connection: %d", | |
521 | 1192 s->proxy->upstream.connection->fd); |
1193 | |
1194 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
|
1195 } |
47709bff4468
nginx-0.0.10-2004-09-09-19:40:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
418
diff
changeset
|
1196 |
1136 | 1197 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
|
1198 } |
521 | 1199 |
1200 | |
1201 static void * | |
1136 | 1202 ngx_mail_proxy_create_conf(ngx_conf_t *cf) |
577 | 1203 { |
1136 | 1204 ngx_mail_proxy_conf_t *pcf; |
577 | 1205 |
1136 | 1206 pcf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_proxy_conf_t)); |
521 | 1207 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
|
1208 return NULL; |
521 | 1209 } |
1210 | |
1211 pcf->enable = NGX_CONF_UNSET; | |
857 | 1212 pcf->pass_error_message = NGX_CONF_UNSET; |
1136 | 1213 pcf->xclient = NGX_CONF_UNSET; |
7725
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
1214 pcf->smtp_auth = NGX_CONF_UNSET; |
539 | 1215 pcf->buffer_size = NGX_CONF_UNSET_SIZE; |
1216 pcf->timeout = NGX_CONF_UNSET_MSEC; | |
521 | 1217 |
1218 return pcf; | |
1219 } | |
1220 | |
1221 | |
1222 static char * | |
1136 | 1223 ngx_mail_proxy_merge_conf(ngx_conf_t *cf, void *parent, void *child) |
521 | 1224 { |
1136 | 1225 ngx_mail_proxy_conf_t *prev = parent; |
1226 ngx_mail_proxy_conf_t *conf = child; | |
521 | 1227 |
539 | 1228 ngx_conf_merge_value(conf->enable, prev->enable, 0); |
857 | 1229 ngx_conf_merge_value(conf->pass_error_message, prev->pass_error_message, 0); |
1136 | 1230 ngx_conf_merge_value(conf->xclient, prev->xclient, 1); |
7725
d63c5373b5ba
Mail: proxy_smtp_auth directive.
Maxim Dounin <mdounin@mdounin.ru>
parents:
7156
diff
changeset
|
1231 ngx_conf_merge_value(conf->smtp_auth, prev->smtp_auth, 0); |
539 | 1232 ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, |
1233 (size_t) ngx_pagesize); | |
1234 ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 24 * 60 * 60000); | |
521 | 1235 |
1236 return NGX_CONF_OK; | |
1237 } |