Annotation of embedaddon/nginx/src/mail/ngx_mail_smtp_module.c, revision 1.1.1.1
1.1 misho 1:
2: /*
3: * Copyright (C) Igor Sysoev
4: * Copyright (C) Nginx, Inc.
5: */
6:
7:
8: #include <ngx_config.h>
9: #include <ngx_core.h>
10: #include <ngx_event.h>
11: #include <ngx_mail.h>
12: #include <ngx_mail_smtp_module.h>
13:
14:
15: static void *ngx_mail_smtp_create_srv_conf(ngx_conf_t *cf);
16: static char *ngx_mail_smtp_merge_srv_conf(ngx_conf_t *cf, void *parent,
17: void *child);
18:
19:
20: static ngx_conf_bitmask_t ngx_mail_smtp_auth_methods[] = {
21: { ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED },
22: { ngx_string("login"), NGX_MAIL_AUTH_LOGIN_ENABLED },
23: { ngx_string("cram-md5"), NGX_MAIL_AUTH_CRAM_MD5_ENABLED },
24: { ngx_string("none"), NGX_MAIL_AUTH_NONE_ENABLED },
25: { ngx_null_string, 0 }
26: };
27:
28:
29: static ngx_str_t ngx_mail_smtp_auth_methods_names[] = {
30: ngx_string("PLAIN"),
31: ngx_string("LOGIN"),
32: ngx_null_string, /* APOP */
33: ngx_string("CRAM-MD5"),
34: ngx_null_string /* NONE */
35: };
36:
37:
38: static ngx_mail_protocol_t ngx_mail_smtp_protocol = {
39: ngx_string("smtp"),
40: { 25, 465, 587, 0 },
41: NGX_MAIL_SMTP_PROTOCOL,
42:
43: ngx_mail_smtp_init_session,
44: ngx_mail_smtp_init_protocol,
45: ngx_mail_smtp_parse_command,
46: ngx_mail_smtp_auth_state,
47:
48: ngx_string("451 4.3.2 Internal server error" CRLF)
49: };
50:
51:
52: static ngx_command_t ngx_mail_smtp_commands[] = {
53:
54: { ngx_string("smtp_client_buffer"),
55: NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
56: ngx_conf_set_size_slot,
57: NGX_MAIL_SRV_CONF_OFFSET,
58: offsetof(ngx_mail_smtp_srv_conf_t, client_buffer_size),
59: NULL },
60:
61: { ngx_string("smtp_greeting_delay"),
62: NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
63: ngx_conf_set_msec_slot,
64: NGX_MAIL_SRV_CONF_OFFSET,
65: offsetof(ngx_mail_smtp_srv_conf_t, greeting_delay),
66: NULL },
67:
68: { ngx_string("smtp_capabilities"),
69: NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
70: ngx_mail_capabilities,
71: NGX_MAIL_SRV_CONF_OFFSET,
72: offsetof(ngx_mail_smtp_srv_conf_t, capabilities),
73: NULL },
74:
75: { ngx_string("smtp_auth"),
76: NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
77: ngx_conf_set_bitmask_slot,
78: NGX_MAIL_SRV_CONF_OFFSET,
79: offsetof(ngx_mail_smtp_srv_conf_t, auth_methods),
80: &ngx_mail_smtp_auth_methods },
81:
82: ngx_null_command
83: };
84:
85:
86: static ngx_mail_module_t ngx_mail_smtp_module_ctx = {
87: &ngx_mail_smtp_protocol, /* protocol */
88:
89: NULL, /* create main configuration */
90: NULL, /* init main configuration */
91:
92: ngx_mail_smtp_create_srv_conf, /* create server configuration */
93: ngx_mail_smtp_merge_srv_conf /* merge server configuration */
94: };
95:
96:
97: ngx_module_t ngx_mail_smtp_module = {
98: NGX_MODULE_V1,
99: &ngx_mail_smtp_module_ctx, /* module context */
100: ngx_mail_smtp_commands, /* module directives */
101: NGX_MAIL_MODULE, /* module type */
102: NULL, /* init master */
103: NULL, /* init module */
104: NULL, /* init process */
105: NULL, /* init thread */
106: NULL, /* exit thread */
107: NULL, /* exit process */
108: NULL, /* exit master */
109: NGX_MODULE_V1_PADDING
110: };
111:
112:
113: static void *
114: ngx_mail_smtp_create_srv_conf(ngx_conf_t *cf)
115: {
116: ngx_mail_smtp_srv_conf_t *sscf;
117:
118: sscf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_smtp_srv_conf_t));
119: if (sscf == NULL) {
120: return NULL;
121: }
122:
123: sscf->client_buffer_size = NGX_CONF_UNSET_SIZE;
124: sscf->greeting_delay = NGX_CONF_UNSET_MSEC;
125:
126: if (ngx_array_init(&sscf->capabilities, cf->pool, 4, sizeof(ngx_str_t))
127: != NGX_OK)
128: {
129: return NULL;
130: }
131:
132: return sscf;
133: }
134:
135:
136: static char *
137: ngx_mail_smtp_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
138: {
139: ngx_mail_smtp_srv_conf_t *prev = parent;
140: ngx_mail_smtp_srv_conf_t *conf = child;
141:
142: u_char *p, *auth, *last;
143: size_t size;
144: ngx_str_t *c;
145: ngx_uint_t i, m, auth_enabled;
146: ngx_mail_core_srv_conf_t *cscf;
147:
148: ngx_conf_merge_size_value(conf->client_buffer_size,
149: prev->client_buffer_size,
150: (size_t) ngx_pagesize);
151:
152: ngx_conf_merge_msec_value(conf->greeting_delay,
153: prev->greeting_delay, 0);
154:
155: ngx_conf_merge_bitmask_value(conf->auth_methods,
156: prev->auth_methods,
157: (NGX_CONF_BITMASK_SET
158: |NGX_MAIL_AUTH_PLAIN_ENABLED
159: |NGX_MAIL_AUTH_LOGIN_ENABLED));
160:
161:
162: cscf = ngx_mail_conf_get_module_srv_conf(cf, ngx_mail_core_module);
163:
164: size = sizeof("220 ESMTP ready" CRLF) - 1 + cscf->server_name.len;
165:
166: p = ngx_pnalloc(cf->pool, size);
167: if (p == NULL) {
168: return NGX_CONF_ERROR;
169: }
170:
171: conf->greeting.len = size;
172: conf->greeting.data = p;
173:
174: *p++ = '2'; *p++ = '2'; *p++ = '0'; *p++ = ' ';
175: p = ngx_cpymem(p, cscf->server_name.data, cscf->server_name.len);
176: ngx_memcpy(p, " ESMTP ready" CRLF, sizeof(" ESMTP ready" CRLF) - 1);
177:
178:
179: size = sizeof("250 " CRLF) - 1 + cscf->server_name.len;
180:
181: p = ngx_pnalloc(cf->pool, size);
182: if (p == NULL) {
183: return NGX_CONF_ERROR;
184: }
185:
186: conf->server_name.len = size;
187: conf->server_name.data = p;
188:
189: *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = ' ';
190: p = ngx_cpymem(p, cscf->server_name.data, cscf->server_name.len);
191: *p++ = CR; *p = LF;
192:
193:
194: if (conf->capabilities.nelts == 0) {
195: conf->capabilities = prev->capabilities;
196: }
197:
198: size = sizeof("250-") - 1 + cscf->server_name.len + sizeof(CRLF) - 1;
199:
200: c = conf->capabilities.elts;
201: for (i = 0; i < conf->capabilities.nelts; i++) {
202: size += sizeof("250 ") - 1 + c[i].len + sizeof(CRLF) - 1;
203: }
204:
205: auth_enabled = 0;
206:
207: for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
208: m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED;
209: m <<= 1, i++)
210: {
211: if (m & conf->auth_methods) {
212: size += 1 + ngx_mail_smtp_auth_methods_names[i].len;
213: auth_enabled = 1;
214: }
215: }
216:
217: if (auth_enabled) {
218: size += sizeof("250 AUTH") - 1 + sizeof(CRLF) - 1;
219: }
220:
221: p = ngx_pnalloc(cf->pool, size);
222: if (p == NULL) {
223: return NGX_CONF_ERROR;
224: }
225:
226: conf->capability.len = size;
227: conf->capability.data = p;
228:
229: last = p;
230:
231: *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = '-';
232: p = ngx_cpymem(p, cscf->server_name.data, cscf->server_name.len);
233: *p++ = CR; *p++ = LF;
234:
235: for (i = 0; i < conf->capabilities.nelts; i++) {
236: last = p;
237: *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = '-';
238: p = ngx_cpymem(p, c[i].data, c[i].len);
239: *p++ = CR; *p++ = LF;
240: }
241:
242: auth = p;
243:
244: if (auth_enabled) {
245: last = p;
246:
247: *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = ' ';
248: *p++ = 'A'; *p++ = 'U'; *p++ = 'T'; *p++ = 'H';
249:
250: for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
251: m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED;
252: m <<= 1, i++)
253: {
254: if (m & conf->auth_methods) {
255: *p++ = ' ';
256: p = ngx_cpymem(p, ngx_mail_smtp_auth_methods_names[i].data,
257: ngx_mail_smtp_auth_methods_names[i].len);
258: }
259: }
260:
261: *p++ = CR; *p = LF;
262:
263: } else {
264: last[3] = ' ';
265: }
266:
267: size += sizeof("250 STARTTLS" CRLF) - 1;
268:
269: p = ngx_pnalloc(cf->pool, size);
270: if (p == NULL) {
271: return NGX_CONF_ERROR;
272: }
273:
274: conf->starttls_capability.len = size;
275: conf->starttls_capability.data = p;
276:
277: p = ngx_cpymem(p, conf->capability.data, conf->capability.len);
278:
279: p = ngx_cpymem(p, "250 STARTTLS" CRLF, sizeof("250 STARTTLS" CRLF) - 1);
280:
281: p = conf->starttls_capability.data
282: + (last - conf->capability.data) + 3;
283: *p = '-';
284:
285: size = (auth - conf->capability.data)
286: + sizeof("250 STARTTLS" CRLF) - 1;
287:
288: p = ngx_pnalloc(cf->pool, size);
289: if (p == NULL) {
290: return NGX_CONF_ERROR;
291: }
292:
293: conf->starttls_only_capability.len = size;
294: conf->starttls_only_capability.data = p;
295:
296: p = ngx_cpymem(p, conf->capability.data, auth - conf->capability.data);
297:
298: ngx_memcpy(p, "250 STARTTLS" CRLF, sizeof("250 STARTTLS" CRLF) - 1);
299:
300: if (last < auth) {
301: p = conf->starttls_only_capability.data
302: + (last - conf->capability.data) + 3;
303: *p = '-';
304: }
305:
306: return NGX_CONF_OK;
307: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>