3 * Copyright (C) Igor Sysoev
4 * Copyright (C) Nginx, Inc.
8 #include <ngx_config.h>
10 #include <ngx_event.h>
12 #include <ngx_mail_pop3_module.h>
15 static void *ngx_mail_pop3_create_srv_conf(ngx_conf_t
*cf
);
16 static char *ngx_mail_pop3_merge_srv_conf(ngx_conf_t
*cf
, void *parent
,
20 static ngx_str_t ngx_mail_pop3_default_capabilities
[] = {
28 static ngx_conf_bitmask_t ngx_mail_pop3_auth_methods
[] = {
29 { ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED
},
30 { ngx_string("apop"), NGX_MAIL_AUTH_APOP_ENABLED
},
31 { ngx_string("cram-md5"), NGX_MAIL_AUTH_CRAM_MD5_ENABLED
},
32 { ngx_null_string
, 0 }
36 static ngx_str_t ngx_mail_pop3_auth_plain_capability
=
37 ngx_string("+OK methods supported:" CRLF
43 static ngx_str_t ngx_mail_pop3_auth_cram_md5_capability
=
44 ngx_string("+OK methods supported:" CRLF
51 static ngx_mail_protocol_t ngx_mail_pop3_protocol
= {
54 NGX_MAIL_POP3_PROTOCOL
,
56 ngx_mail_pop3_init_session
,
57 ngx_mail_pop3_init_protocol
,
58 ngx_mail_pop3_parse_command
,
59 ngx_mail_pop3_auth_state
,
61 ngx_string("-ERR internal server error" CRLF
)
65 static ngx_command_t ngx_mail_pop3_commands
[] = {
67 { ngx_string("pop3_capabilities"),
68 NGX_MAIL_MAIN_CONF
|NGX_MAIL_SRV_CONF
|NGX_CONF_1MORE
,
69 ngx_mail_capabilities
,
70 NGX_MAIL_SRV_CONF_OFFSET
,
71 offsetof(ngx_mail_pop3_srv_conf_t
, capabilities
),
74 { ngx_string("pop3_auth"),
75 NGX_MAIL_MAIN_CONF
|NGX_MAIL_SRV_CONF
|NGX_CONF_1MORE
,
76 ngx_conf_set_bitmask_slot
,
77 NGX_MAIL_SRV_CONF_OFFSET
,
78 offsetof(ngx_mail_pop3_srv_conf_t
, auth_methods
),
79 &ngx_mail_pop3_auth_methods
},
85 static ngx_mail_module_t ngx_mail_pop3_module_ctx
= {
86 &ngx_mail_pop3_protocol
, /* protocol */
88 NULL
, /* create main configuration */
89 NULL
, /* init main configuration */
91 ngx_mail_pop3_create_srv_conf
, /* create server configuration */
92 ngx_mail_pop3_merge_srv_conf
/* merge server configuration */
96 ngx_module_t ngx_mail_pop3_module
= {
98 &ngx_mail_pop3_module_ctx
, /* module context */
99 ngx_mail_pop3_commands
, /* module directives */
100 NGX_MAIL_MODULE
, /* module type */
101 NULL
, /* init master */
102 NULL
, /* init module */
103 NULL
, /* init process */
104 NULL
, /* init thread */
105 NULL
, /* exit thread */
106 NULL
, /* exit process */
107 NULL
, /* exit master */
108 NGX_MODULE_V1_PADDING
113 ngx_mail_pop3_create_srv_conf(ngx_conf_t
*cf
)
115 ngx_mail_pop3_srv_conf_t
*pscf
;
117 pscf
= ngx_pcalloc(cf
->pool
, sizeof(ngx_mail_pop3_srv_conf_t
));
122 if (ngx_array_init(&pscf
->capabilities
, cf
->pool
, 4, sizeof(ngx_str_t
))
133 ngx_mail_pop3_merge_srv_conf(ngx_conf_t
*cf
, void *parent
, void *child
)
135 ngx_mail_pop3_srv_conf_t
*prev
= parent
;
136 ngx_mail_pop3_srv_conf_t
*conf
= child
;
139 size_t size
, stls_only_size
;
143 ngx_conf_merge_bitmask_value(conf
->auth_methods
,
145 (NGX_CONF_BITMASK_SET
146 |NGX_MAIL_AUTH_PLAIN_ENABLED
));
148 if (conf
->capabilities
.nelts
== 0) {
149 conf
->capabilities
= prev
->capabilities
;
152 if (conf
->capabilities
.nelts
== 0) {
154 for (d
= ngx_mail_pop3_default_capabilities
; d
->len
; d
++) {
155 c
= ngx_array_push(&conf
->capabilities
);
157 return NGX_CONF_ERROR
;
164 size
= sizeof("+OK Capability list follows" CRLF
) - 1
165 + sizeof("." CRLF
) - 1;
167 stls_only_size
= size
+ sizeof("STLS" CRLF
) - 1;
169 c
= conf
->capabilities
.elts
;
170 for (i
= 0; i
< conf
->capabilities
.nelts
; i
++) {
171 size
+= c
[i
].len
+ sizeof(CRLF
) - 1;
173 if (ngx_strcasecmp(c
[i
].data
, (u_char
*) "USER") == 0) {
177 stls_only_size
+= c
[i
].len
+ sizeof(CRLF
) - 1;
180 if (conf
->auth_methods
& NGX_MAIL_AUTH_CRAM_MD5_ENABLED
) {
181 size
+= sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF
) - 1;
184 size
+= sizeof("SASL LOGIN PLAIN" CRLF
) - 1;
187 p
= ngx_pnalloc(cf
->pool
, size
);
189 return NGX_CONF_ERROR
;
192 conf
->capability
.len
= size
;
193 conf
->capability
.data
= p
;
195 p
= ngx_cpymem(p
, "+OK Capability list follows" CRLF
,
196 sizeof("+OK Capability list follows" CRLF
) - 1);
198 for (i
= 0; i
< conf
->capabilities
.nelts
; i
++) {
199 p
= ngx_cpymem(p
, c
[i
].data
, c
[i
].len
);
200 *p
++ = CR
; *p
++ = LF
;
203 if (conf
->auth_methods
& NGX_MAIL_AUTH_CRAM_MD5_ENABLED
) {
204 p
= ngx_cpymem(p
, "SASL LOGIN PLAIN CRAM-MD5" CRLF
,
205 sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF
) - 1);
208 p
= ngx_cpymem(p
, "SASL LOGIN PLAIN" CRLF
,
209 sizeof("SASL LOGIN PLAIN" CRLF
) - 1);
212 *p
++ = '.'; *p
++ = CR
; *p
= LF
;
215 size
+= sizeof("STLS" CRLF
) - 1;
217 p
= ngx_pnalloc(cf
->pool
, size
);
219 return NGX_CONF_ERROR
;
222 conf
->starttls_capability
.len
= size
;
223 conf
->starttls_capability
.data
= p
;
225 p
= ngx_cpymem(p
, conf
->capability
.data
,
226 conf
->capability
.len
- (sizeof("." CRLF
) - 1));
228 p
= ngx_cpymem(p
, "STLS" CRLF
, sizeof("STLS" CRLF
) - 1);
229 *p
++ = '.'; *p
++ = CR
; *p
= LF
;
232 if (conf
->auth_methods
& NGX_MAIL_AUTH_CRAM_MD5_ENABLED
) {
233 conf
->auth_capability
= ngx_mail_pop3_auth_cram_md5_capability
;
236 conf
->auth_capability
= ngx_mail_pop3_auth_plain_capability
;
240 p
= ngx_pnalloc(cf
->pool
, stls_only_size
);
242 return NGX_CONF_ERROR
;
245 conf
->starttls_only_capability
.len
= stls_only_size
;
246 conf
->starttls_only_capability
.data
= p
;
248 p
= ngx_cpymem(p
, "+OK Capability list follows" CRLF
,
249 sizeof("+OK Capability list follows" CRLF
) - 1);
251 for (i
= 0; i
< conf
->capabilities
.nelts
; i
++) {
252 if (ngx_strcasecmp(c
[i
].data
, (u_char
*) "USER") == 0) {
256 p
= ngx_cpymem(p
, c
[i
].data
, c
[i
].len
);
257 *p
++ = CR
; *p
++ = LF
;
260 p
= ngx_cpymem(p
, "STLS" CRLF
, sizeof("STLS" CRLF
) - 1);
261 *p
++ = '.'; *p
++ = CR
; *p
= LF
;