1 
2 /*
3  * Copyright (C) Igor Sysoev
4  * Copyright (C) Nginx, Inc.
5  */
6 
7 
8 #ifndef _NGX_MAIL_H_INCLUDED_
9 #define _NGX_MAIL_H_INCLUDED_
10 
11 
12 #include <ngx_config.h>
13 #include <ngx_core.h>
14 #include <ngx_event.h>
15 #include <ngx_event_connect.h>
16 
17 #if (NGX_MAIL_SSL)
18 #include <ngx_mail_ssl_module.h>
19 #endif
20 
21 
22 
23 typedef struct {
24     void                  **main_conf;
25     void                  **srv_conf;
26 } ngx_mail_conf_ctx_t;
27 
28 
29 typedef struct {
30     struct sockaddr        *sockaddr;
31     socklen_t               socklen;
32     ngx_str_t               addr_text;
33 
34     /* server ctx */
35     ngx_mail_conf_ctx_t    *ctx;
36 
37     unsigned                bind:1;
38     unsigned                wildcard:1;
39     unsigned                ssl:1;
40 #if (NGX_HAVE_INET6)
41     unsigned                ipv6only:1;
42 #endif
43     unsigned                so_keepalive:2;
44     unsigned                proxy_protocol:1;
45 #if (NGX_HAVE_KEEPALIVE_TUNABLE)
46     int                     tcp_keepidle;
47     int                     tcp_keepintvl;
48     int                     tcp_keepcnt;
49 #endif
50     int                     backlog;
51     int                     rcvbuf;
52     int                     sndbuf;
53 } ngx_mail_listen_t;
54 
55 
56 typedef struct {
57     ngx_mail_conf_ctx_t    *ctx;
58     ngx_str_t               addr_text;
59     unsigned                ssl:1;
60     unsigned                proxy_protocol:1;
61 } ngx_mail_addr_conf_t;
62 
63 typedef struct {
64     in_addr_t               addr;
65     ngx_mail_addr_conf_t    conf;
66 } ngx_mail_in_addr_t;
67 
68 
69 #if (NGX_HAVE_INET6)
70 
71 typedef struct {
72     struct in6_addr         addr6;
73     ngx_mail_addr_conf_t    conf;
74 } ngx_mail_in6_addr_t;
75 
76 #endif
77 
78 
79 typedef struct {
80     /* ngx_mail_in_addr_t or ngx_mail_in6_addr_t */
81     void                   *addrs;
82     ngx_uint_t              naddrs;
83 } ngx_mail_port_t;
84 
85 
86 typedef struct {
87     int                     family;
88     in_port_t               port;
89     ngx_array_t             addrs;       /* array of ngx_mail_conf_addr_t */
90 } ngx_mail_conf_port_t;
91 
92 
93 typedef struct {
94     ngx_mail_listen_t       opt;
95 } ngx_mail_conf_addr_t;
96 
97 
98 typedef struct {
99     ngx_array_t             servers;     /* ngx_mail_core_srv_conf_t */
100     ngx_array_t             listen;      /* ngx_mail_listen_t */
101 } ngx_mail_core_main_conf_t;
102 
103 
104 #define NGX_MAIL_POP3_PROTOCOL  0
105 #define NGX_MAIL_IMAP_PROTOCOL  1
106 #define NGX_MAIL_SMTP_PROTOCOL  2
107 
108 
109 typedef struct ngx_mail_protocol_s  ngx_mail_protocol_t;
110 
111 
112 typedef struct {
113     ngx_mail_protocol_t    *protocol;
114 
115     ngx_msec_t              timeout;
116     ngx_msec_t              resolver_timeout;
117 
118     ngx_str_t               server_name;
119 
120     u_char                 *file_name;
121     ngx_uint_t              line;
122 
123     ngx_resolver_t         *resolver;
124     ngx_log_t              *error_log;
125 
126     /* server ctx */
127     ngx_mail_conf_ctx_t    *ctx;
128 
129     ngx_uint_t              listen;  /* unsigned  listen:1; */
130 } ngx_mail_core_srv_conf_t;
131 
132 
133 typedef enum {
134     ngx_pop3_start = 0,
135     ngx_pop3_user,
136     ngx_pop3_passwd,
137     ngx_pop3_auth_login_username,
138     ngx_pop3_auth_login_password,
139     ngx_pop3_auth_plain,
140     ngx_pop3_auth_cram_md5,
141     ngx_pop3_auth_external
142 } ngx_pop3_state_e;
143 
144 
145 typedef enum {
146     ngx_imap_start = 0,
147     ngx_imap_auth_login_username,
148     ngx_imap_auth_login_password,
149     ngx_imap_auth_plain,
150     ngx_imap_auth_cram_md5,
151     ngx_imap_auth_external,
152     ngx_imap_login,
153     ngx_imap_user,
154     ngx_imap_passwd
155 } ngx_imap_state_e;
156 
157 
158 typedef enum {
159     ngx_smtp_start = 0,
160     ngx_smtp_auth_login_username,
161     ngx_smtp_auth_login_password,
162     ngx_smtp_auth_plain,
163     ngx_smtp_auth_cram_md5,
164     ngx_smtp_auth_external,
165     ngx_smtp_helo,
166     ngx_smtp_helo_xclient,
167     ngx_smtp_helo_auth,
168     ngx_smtp_helo_from,
169     ngx_smtp_xclient,
170     ngx_smtp_xclient_from,
171     ngx_smtp_xclient_helo,
172     ngx_smtp_xclient_auth,
173     ngx_smtp_from,
174     ngx_smtp_to
175 } ngx_smtp_state_e;
176 
177 
178 typedef struct {
179     ngx_peer_connection_t   upstream;
180     ngx_buf_t              *buffer;
181     ngx_uint_t              proxy_protocol;  /* unsigned  proxy_protocol:1; */
182 } ngx_mail_proxy_ctx_t;
183 
184 
185 typedef struct {
186     uint32_t                signature;         /* "MAIL" */
187 
188     ngx_connection_t       *connection;
189 
190     ngx_str_t               out;
191     ngx_buf_t              *buffer;
192 
193     void                  **ctx;
194     void                  **main_conf;
195     void                  **srv_conf;
196 
197     ngx_resolver_ctx_t     *resolver_ctx;
198 
199     ngx_mail_proxy_ctx_t   *proxy;
200 
201     ngx_uint_t              mail_state;
202 
203     unsigned                ssl:1;
204     unsigned                protocol:3;
205     unsigned                blocked:1;
206     unsigned                quit:1;
207     unsigned                quoted:1;
208     unsigned                backslash:1;
209     unsigned                no_sync_literal:1;
210     unsigned                starttls:1;
211     unsigned                esmtp:1;
212     unsigned                auth_method:3;
213     unsigned                auth_wait:1;
214 
215     ngx_str_t               login;
216     ngx_str_t               passwd;
217 
218     ngx_str_t               salt;
219     ngx_str_t               tag;
220     ngx_str_t               tagged_line;
221     ngx_str_t               text;
222 
223     ngx_str_t              *addr_text;
224     ngx_str_t               host;
225     ngx_str_t               smtp_helo;
226     ngx_str_t               smtp_from;
227     ngx_str_t               smtp_to;
228 
229     ngx_str_t               cmd;
230 
231     ngx_uint_t              command;
232     ngx_array_t             args;
233 
234     ngx_uint_t              login_attempt;
235 
236     /* used to parse POP3/IMAP/SMTP command */
237 
238     ngx_uint_t              state;
239     u_char                 *cmd_start;
240     u_char                 *arg_start;
241     u_char                 *arg_end;
242     ngx_uint_t              literal_len;
243 } ngx_mail_session_t;
244 
245 
246 typedef struct {
247     ngx_str_t              *client;
248     ngx_mail_session_t     *session;
249 } ngx_mail_log_ctx_t;
250 
251 
252 #define NGX_POP3_USER          1
253 #define NGX_POP3_PASS          2
254 #define NGX_POP3_CAPA          3
255 #define NGX_POP3_QUIT          4
256 #define NGX_POP3_NOOP          5
257 #define NGX_POP3_STLS          6
258 #define NGX_POP3_APOP          7
259 #define NGX_POP3_AUTH          8
260 #define NGX_POP3_STAT          9
261 #define NGX_POP3_LIST          10
262 #define NGX_POP3_RETR          11
263 #define NGX_POP3_DELE          12
264 #define NGX_POP3_RSET          13
265 #define NGX_POP3_TOP           14
266 #define NGX_POP3_UIDL          15
267 
268 
269 #define NGX_IMAP_LOGIN         1
270 #define NGX_IMAP_LOGOUT        2
271 #define NGX_IMAP_CAPABILITY    3
272 #define NGX_IMAP_NOOP          4
273 #define NGX_IMAP_STARTTLS      5
274 
275 #define NGX_IMAP_NEXT          6
276 
277 #define NGX_IMAP_AUTHENTICATE  7
278 
279 
280 #define NGX_SMTP_HELO          1
281 #define NGX_SMTP_EHLO          2
282 #define NGX_SMTP_AUTH          3
283 #define NGX_SMTP_QUIT          4
284 #define NGX_SMTP_NOOP          5
285 #define NGX_SMTP_MAIL          6
286 #define NGX_SMTP_RSET          7
287 #define NGX_SMTP_RCPT          8
288 #define NGX_SMTP_DATA          9
289 #define NGX_SMTP_VRFY          10
290 #define NGX_SMTP_EXPN          11
291 #define NGX_SMTP_HELP          12
292 #define NGX_SMTP_STARTTLS      13
293 
294 
295 #define NGX_MAIL_AUTH_PLAIN             0
296 #define NGX_MAIL_AUTH_LOGIN             1
297 #define NGX_MAIL_AUTH_LOGIN_USERNAME    2
298 #define NGX_MAIL_AUTH_APOP              3
299 #define NGX_MAIL_AUTH_CRAM_MD5          4
300 #define NGX_MAIL_AUTH_EXTERNAL          5
301 #define NGX_MAIL_AUTH_NONE              6
302 
303 
304 #define NGX_MAIL_AUTH_PLAIN_ENABLED     0x0002
305 #define NGX_MAIL_AUTH_LOGIN_ENABLED     0x0004
306 #define NGX_MAIL_AUTH_APOP_ENABLED      0x0008
307 #define NGX_MAIL_AUTH_CRAM_MD5_ENABLED  0x0010
308 #define NGX_MAIL_AUTH_EXTERNAL_ENABLED  0x0020
309 #define NGX_MAIL_AUTH_NONE_ENABLED      0x0040
310 
311 
312 #define NGX_MAIL_PARSE_INVALID_COMMAND  20
313 
314 
315 typedef void (*ngx_mail_init_session_pt)(ngx_mail_session_t *s,
316     ngx_connection_t *c);
317 typedef void (*ngx_mail_init_protocol_pt)(ngx_event_t *rev);
318 typedef void (*ngx_mail_auth_state_pt)(ngx_event_t *rev);
319 typedef ngx_int_t (*ngx_mail_parse_command_pt)(ngx_mail_session_t *s);
320 
321 
322 struct ngx_mail_protocol_s {
323     ngx_str_t                   name;
324     in_port_t                   port[4];
325     ngx_uint_t                  type;
326 
327     ngx_mail_init_session_pt    init_session;
328     ngx_mail_init_protocol_pt   init_protocol;
329     ngx_mail_parse_command_pt   parse_command;
330     ngx_mail_auth_state_pt      auth_state;
331 
332     ngx_str_t                   internal_server_error;
333     ngx_str_t                   cert_error;
334     ngx_str_t                   no_cert;
335 };
336 
337 
338 typedef struct {
339     ngx_mail_protocol_t        *protocol;
340 
341     void                       *(*create_main_conf)(ngx_conf_t *cf);
342     char                       *(*init_main_conf)(ngx_conf_t *cf, void *conf);
343 
344     void                       *(*create_srv_conf)(ngx_conf_t *cf);
345     char                       *(*merge_srv_conf)(ngx_conf_t *cf, void *prev,
346                                                   void *conf);
347 } ngx_mail_module_t;
348 
349 
350 #define NGX_MAIL_MODULE         0x4C49414D     /* "MAIL" */
351 
352 #define NGX_MAIL_MAIN_CONF      0x02000000
353 #define NGX_MAIL_SRV_CONF       0x04000000
354 
355 
356 #define NGX_MAIL_MAIN_CONF_OFFSET  offsetof(ngx_mail_conf_ctx_t, main_conf)
357 #define NGX_MAIL_SRV_CONF_OFFSET   offsetof(ngx_mail_conf_ctx_t, srv_conf)
358 
359 
360 #define ngx_mail_get_module_ctx(s, module)     (s)->ctx[module.ctx_index]
361 #define ngx_mail_set_ctx(s, c, module)         s->ctx[module.ctx_index] = c;
362 #define ngx_mail_delete_ctx(s, module)         s->ctx[module.ctx_index] = NULL;
363 
364 
365 #define ngx_mail_get_module_main_conf(s, module)                             \
366     (s)->main_conf[module.ctx_index]
367 #define ngx_mail_get_module_srv_conf(s, module)  (s)->srv_conf[module.ctx_index]
368 
369 #define ngx_mail_conf_get_module_main_conf(cf, module)                       \
370     ((ngx_mail_conf_ctx_t *) cf->ctx)->main_conf[module.ctx_index]
371 #define ngx_mail_conf_get_module_srv_conf(cf, module)                        \
372     ((ngx_mail_conf_ctx_t *) cf->ctx)->srv_conf[module.ctx_index]
373 
374 
375 #if (NGX_MAIL_SSL)
376 void ngx_mail_starttls_handler(ngx_event_t *rev);
377 ngx_int_t ngx_mail_starttls_only(ngx_mail_session_t *s, ngx_connection_t *c);
378 #endif
379 
380 
381 void ngx_mail_init_connection(ngx_connection_t *c);
382 
383 ngx_int_t ngx_mail_salt(ngx_mail_session_t *s, ngx_connection_t *c,
384     ngx_mail_core_srv_conf_t *cscf);
385 ngx_int_t ngx_mail_auth_plain(ngx_mail_session_t *s, ngx_connection_t *c,
386     ngx_uint_t n);
387 ngx_int_t ngx_mail_auth_login_username(ngx_mail_session_t *s,
388     ngx_connection_t *c, ngx_uint_t n);
389 ngx_int_t ngx_mail_auth_login_password(ngx_mail_session_t *s,
390     ngx_connection_t *c);
391 ngx_int_t ngx_mail_auth_cram_md5_salt(ngx_mail_session_t *s,
392     ngx_connection_t *c, char *prefix, size_t len);
393 ngx_int_t ngx_mail_auth_cram_md5(ngx_mail_session_t *s, ngx_connection_t *c);
394 ngx_int_t ngx_mail_auth_external(ngx_mail_session_t *s, ngx_connection_t *c,
395     ngx_uint_t n);
396 ngx_int_t ngx_mail_auth_parse(ngx_mail_session_t *s, ngx_connection_t *c);
397 
398 void ngx_mail_send(ngx_event_t *wev);
399 ngx_int_t ngx_mail_read_command(ngx_mail_session_t *s, ngx_connection_t *c);
400 void ngx_mail_auth(ngx_mail_session_t *s, ngx_connection_t *c);
401 void ngx_mail_close_connection(ngx_connection_t *c);
402 void ngx_mail_session_internal_server_error(ngx_mail_session_t *s);
403 u_char *ngx_mail_log_error(ngx_log_t *log, u_char *buf, size_t len);
404 
405 
406 char *ngx_mail_capabilities(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
407 
408 
409 /* STUB */
410 void ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_addr_t *peer);
411 void ngx_mail_auth_http_init(ngx_mail_session_t *s);
412 ngx_int_t ngx_mail_realip_handler(ngx_mail_session_t *s);
413 /**/
414 
415 
416 extern ngx_uint_t    ngx_mail_max_module;
417 extern ngx_module_t  ngx_mail_core_module;
418 
419 
420 #endif /* _NGX_MAIL_H_INCLUDED_ */
421