comparison src/mail/ngx_mail_smtp_handler.c @ 410:cd9cb7a3ff9e

Merge with nginx 0.7.8.
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 11 Aug 2008 22:07:06 +0400
parents 52b28d322d76 984bb0b1399b
children e2df123bbbe2
comparison
equal deleted inserted replaced
409:52b28d322d76 410:cd9cb7a3ff9e
9 #include <ngx_event.h> 9 #include <ngx_event.h>
10 #include <ngx_mail.h> 10 #include <ngx_mail.h>
11 #include <ngx_mail_smtp_module.h> 11 #include <ngx_mail_smtp_module.h>
12 12
13 13
14 static void ngx_mail_smtp_resolve_addr_handler(ngx_resolver_ctx_t *ctx);
15 static void ngx_mail_smtp_resolve_name_handler(ngx_resolver_ctx_t *ctx);
16 static void ngx_mail_smtp_greeting(ngx_mail_session_t *s, ngx_connection_t *c);
14 static void ngx_mail_smtp_invalid_pipelining(ngx_event_t *rev); 17 static void ngx_mail_smtp_invalid_pipelining(ngx_event_t *rev);
15 static ngx_int_t ngx_mail_smtp_create_buffer(ngx_mail_session_t *s, 18 static ngx_int_t ngx_mail_smtp_create_buffer(ngx_mail_session_t *s,
16 ngx_connection_t *c); 19 ngx_connection_t *c);
17 20
18 static ngx_int_t ngx_mail_smtp_helo(ngx_mail_session_t *s, ngx_connection_t *c); 21 static ngx_int_t ngx_mail_smtp_helo(ngx_mail_session_t *s, ngx_connection_t *c);
29 ngx_connection_t *c, char *err); 32 ngx_connection_t *c, char *err);
30 33
31 34
32 static u_char smtp_ok[] = "250 2.0.0 OK" CRLF; 35 static u_char smtp_ok[] = "250 2.0.0 OK" CRLF;
33 static u_char smtp_bye[] = "221 2.0.0 Bye" CRLF; 36 static u_char smtp_bye[] = "221 2.0.0 Bye" CRLF;
37 static u_char smtp_starttls[] = "220 2.0.0 Start TLS" CRLF;
34 static u_char smtp_next[] = "334 " CRLF; 38 static u_char smtp_next[] = "334 " CRLF;
35 static u_char smtp_username[] = "334 VXNlcm5hbWU6" CRLF; 39 static u_char smtp_username[] = "334 VXNlcm5hbWU6" CRLF;
36 static u_char smtp_password[] = "334 UGFzc3dvcmQ6" CRLF; 40 static u_char smtp_password[] = "334 UGFzc3dvcmQ6" CRLF;
37 static u_char smtp_invalid_command[] = "500 5.5.1 Invalid command" CRLF; 41 static u_char smtp_invalid_command[] = "500 5.5.1 Invalid command" CRLF;
38 static u_char smtp_invalid_pipelining[] = 42 static u_char smtp_invalid_pipelining[] =
40 static u_char smtp_invalid_argument[] = "501 5.5.4 Invalid argument" CRLF; 44 static u_char smtp_invalid_argument[] = "501 5.5.4 Invalid argument" CRLF;
41 static u_char smtp_auth_required[] = "530 5.7.1 Authentication required" CRLF; 45 static u_char smtp_auth_required[] = "530 5.7.1 Authentication required" CRLF;
42 static u_char smtp_bad_sequence[] = "503 5.5.1 Bad sequence of commands" CRLF; 46 static u_char smtp_bad_sequence[] = "503 5.5.1 Bad sequence of commands" CRLF;
43 47
44 48
49 static ngx_str_t smtp_unavailable = ngx_string("[UNAVAILABLE]");
50 static ngx_str_t smtp_tempunavail = ngx_string("[TEMPUNAVAIL]");
51
52
45 void 53 void
46 ngx_mail_smtp_init_session(ngx_mail_session_t *s, ngx_connection_t *c) 54 ngx_mail_smtp_init_session(ngx_mail_session_t *s, ngx_connection_t *c)
55 {
56 struct sockaddr_in *sin;
57 ngx_resolver_ctx_t *ctx;
58 ngx_mail_core_srv_conf_t *cscf;
59
60 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
61
62 if (cscf->resolver == NULL) {
63 s->host = smtp_unavailable;
64 ngx_mail_smtp_greeting(s, c);
65 return;
66 }
67
68 c->log->action = "in resolving client address";
69
70 ctx = ngx_resolve_start(cscf->resolver, NULL);
71 if (ctx == NULL) {
72 ngx_mail_close_connection(c);
73 return;
74 }
75
76 /* AF_INET only */
77
78 sin = (struct sockaddr_in *) c->sockaddr;
79
80 ctx->addr = sin->sin_addr.s_addr;
81 ctx->handler = ngx_mail_smtp_resolve_addr_handler;
82 ctx->data = s;
83 ctx->timeout = cscf->resolver_timeout;
84
85 if (ngx_resolve_addr(ctx) != NGX_OK) {
86 ngx_mail_close_connection(c);
87 }
88 }
89
90
91 static void
92 ngx_mail_smtp_resolve_addr_handler(ngx_resolver_ctx_t *ctx)
93 {
94 ngx_connection_t *c;
95 ngx_mail_session_t *s;
96 ngx_mail_core_srv_conf_t *cscf;
97
98 s = ctx->data;
99 c = s->connection;
100
101 if (ctx->state) {
102 ngx_log_error(NGX_LOG_ERR, c->log, 0,
103 "%V could not be resolved (%i: %s)",
104 &c->addr_text, ctx->state,
105 ngx_resolver_strerror(ctx->state));
106
107 if (ctx->state == NGX_RESOLVE_NXDOMAIN) {
108 s->host = smtp_unavailable;
109
110 } else {
111 s->host = smtp_tempunavail;
112 }
113
114 ngx_resolve_addr_done(ctx);
115
116 ngx_mail_smtp_greeting(s, s->connection);
117
118 return;
119 }
120
121 c->log->action = "in resolving client hostname";
122
123 s->host.data = ngx_pstrdup(c->pool, &ctx->name);
124 if (s->host.data == NULL) {
125 ngx_resolve_addr_done(ctx);
126 ngx_mail_close_connection(c);
127 return;
128 }
129
130 s->host.len = ctx->name.len;
131
132 ngx_resolve_addr_done(ctx);
133
134 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
135 "address resolved: %V", &s->host);
136
137 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
138
139 ctx = ngx_resolve_start(cscf->resolver, NULL);
140 if (ctx == NULL) {
141 ngx_mail_close_connection(c);
142 return;
143 }
144
145 ctx->name = s->host;
146 ctx->type = NGX_RESOLVE_A;
147 ctx->handler = ngx_mail_smtp_resolve_name_handler;
148 ctx->data = s;
149 ctx->timeout = cscf->resolver_timeout;
150
151 if (ngx_resolve_name(ctx) != NGX_OK) {
152 ngx_mail_close_connection(c);
153 }
154 }
155
156
157 static void
158 ngx_mail_smtp_resolve_name_handler(ngx_resolver_ctx_t *ctx)
159 {
160 in_addr_t addr;
161 ngx_uint_t i;
162 ngx_connection_t *c;
163 struct sockaddr_in *sin;
164 ngx_mail_session_t *s;
165
166 s = ctx->data;
167 c = s->connection;
168
169 if (ctx->state) {
170 ngx_log_error(NGX_LOG_ERR, c->log, 0,
171 "%V could not be resolved (%i: %s)",
172 &ctx->name, ctx->state,
173 ngx_resolver_strerror(ctx->state));
174
175 if (ctx->state == NGX_RESOLVE_NXDOMAIN) {
176 s->host = smtp_unavailable;
177
178 } else {
179 s->host = smtp_tempunavail;
180 }
181
182 } else {
183
184 /* AF_INET only */
185
186 sin = (struct sockaddr_in *) c->sockaddr;
187
188 for (i = 0; i < ctx->naddrs; i++) {
189
190 addr = ctx->addrs[i];
191
192 ngx_log_debug4(NGX_LOG_DEBUG_MAIL, c->log, 0,
193 "name was resolved to %ud.%ud.%ud.%ud",
194 (ntohl(addr) >> 24) & 0xff,
195 (ntohl(addr) >> 16) & 0xff,
196 (ntohl(addr) >> 8) & 0xff,
197 ntohl(addr) & 0xff);
198
199 if (addr == sin->sin_addr.s_addr) {
200 goto found;
201 }
202 }
203
204 s->host = smtp_unavailable;
205 }
206
207 found:
208
209 ngx_resolve_name_done(ctx);
210
211 ngx_mail_smtp_greeting(s, c);
212 }
213
214
215 static void
216 ngx_mail_smtp_greeting(ngx_mail_session_t *s, ngx_connection_t *c)
47 { 217 {
48 ngx_msec_t timeout; 218 ngx_msec_t timeout;
49 ngx_mail_core_srv_conf_t *cscf; 219 ngx_mail_core_srv_conf_t *cscf;
50 ngx_mail_smtp_srv_conf_t *sscf; 220 ngx_mail_smtp_srv_conf_t *sscf;
221
222 ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
223 "smtp greeting for \"%V\"", &s->host);
51 224
52 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); 225 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
53 sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module); 226 sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module);
54 227
55 timeout = sscf->greeting_delay ? sscf->greeting_delay : cscf->timeout; 228 timeout = sscf->greeting_delay ? sscf->greeting_delay : cscf->timeout;
258 case NGX_SMTP_NOOP: 431 case NGX_SMTP_NOOP:
259 break; 432 break;
260 433
261 case NGX_SMTP_STARTTLS: 434 case NGX_SMTP_STARTTLS:
262 rc = ngx_mail_smtp_starttls(s, c); 435 rc = ngx_mail_smtp_starttls(s, c);
436 s->out.len = sizeof(smtp_starttls) - 1;
437 s->out.data = smtp_starttls;
263 break; 438 break;
264 439
265 default: 440 default:
266 rc = NGX_MAIL_PARSE_INVALID_COMMAND; 441 rc = NGX_MAIL_PARSE_INVALID_COMMAND;
267 break; 442 break;
327 static ngx_int_t 502 static ngx_int_t
328 ngx_mail_smtp_helo(ngx_mail_session_t *s, ngx_connection_t *c) 503 ngx_mail_smtp_helo(ngx_mail_session_t *s, ngx_connection_t *c)
329 { 504 {
330 ngx_str_t *arg; 505 ngx_str_t *arg;
331 ngx_mail_smtp_srv_conf_t *sscf; 506 ngx_mail_smtp_srv_conf_t *sscf;
332 #if (NGX_MAIL_SSL)
333 ngx_mail_ssl_conf_t *sslcf;
334 #endif
335 507
336 if (s->args.nelts != 1) { 508 if (s->args.nelts != 1) {
337 s->out.len = sizeof(smtp_invalid_argument) - 1; 509 s->out.len = sizeof(smtp_invalid_argument) - 1;
338 s->out.data = smtp_invalid_argument; 510 s->out.data = smtp_invalid_argument;
339 s->state = 0; 511 s->state = 0;
342 514
343 arg = s->args.elts; 515 arg = s->args.elts;
344 516
345 s->smtp_helo.len = arg[0].len; 517 s->smtp_helo.len = arg[0].len;
346 518
347 s->smtp_helo.data = ngx_palloc(c->pool, arg[0].len); 519 s->smtp_helo.data = ngx_pnalloc(c->pool, arg[0].len);
348 if (s->smtp_helo.data == NULL) { 520 if (s->smtp_helo.data == NULL) {
349 return NGX_ERROR; 521 return NGX_ERROR;
350 } 522 }
351 523
352 ngx_memcpy(s->smtp_helo.data, arg[0].data, arg[0].len); 524 ngx_memcpy(s->smtp_helo.data, arg[0].data, arg[0].len);
365 s->esmtp = 1; 537 s->esmtp = 1;
366 538
367 #if (NGX_MAIL_SSL) 539 #if (NGX_MAIL_SSL)
368 540
369 if (c->ssl == NULL) { 541 if (c->ssl == NULL) {
542 ngx_mail_ssl_conf_t *sslcf;
543
370 sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module); 544 sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
371 545
372 if (sslcf->starttls == NGX_MAIL_STARTTLS_ON) { 546 if (sslcf->starttls == NGX_MAIL_STARTTLS_ON) {
373 s->out = sscf->starttls_capability; 547 s->out = sscf->starttls_capability;
374 return NGX_OK; 548 return NGX_OK;