Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ngx_mail_pop3_module.c
Go to the documentation of this file.
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_pop3_module.h>
13 
14 
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,
17  void *child);
18 
19 
20 static ngx_str_t ngx_mail_pop3_default_capabilities[] = {
21  ngx_string("TOP"),
22  ngx_string("USER"),
23  ngx_string("UIDL"),
25 };
26 
27 
28 static ngx_conf_bitmask_t ngx_mail_pop3_auth_methods[] = {
32  { ngx_null_string, 0 }
33 };
34 
35 
36 static ngx_str_t ngx_mail_pop3_auth_plain_capability =
37  ngx_string("+OK methods supported:" CRLF
38  "LOGIN" CRLF
39  "PLAIN" CRLF
40  "." CRLF);
41 
42 
43 static ngx_str_t ngx_mail_pop3_auth_cram_md5_capability =
44  ngx_string("+OK methods supported:" CRLF
45  "LOGIN" CRLF
46  "PLAIN" CRLF
47  "CRAM-MD5" CRLF
48  "." CRLF);
49 
50 
51 static ngx_mail_protocol_t ngx_mail_pop3_protocol = {
52  ngx_string("pop3"),
53  { 110, 995, 0, 0 },
55 
60 
61  ngx_string("-ERR internal server error" CRLF)
62 };
63 
64 
65 static ngx_command_t ngx_mail_pop3_commands[] = {
66 
67  { ngx_string("pop3_capabilities"),
71  offsetof(ngx_mail_pop3_srv_conf_t, capabilities),
72  NULL },
73 
74  { ngx_string("pop3_auth"),
78  offsetof(ngx_mail_pop3_srv_conf_t, auth_methods),
79  &ngx_mail_pop3_auth_methods },
80 
82 };
83 
84 
85 static ngx_mail_module_t ngx_mail_pop3_module_ctx = {
86  &ngx_mail_pop3_protocol, /* protocol */
87 
88  NULL, /* create main configuration */
89  NULL, /* init main configuration */
90 
91  ngx_mail_pop3_create_srv_conf, /* create server configuration */
92  ngx_mail_pop3_merge_srv_conf /* merge server configuration */
93 };
94 
95 
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 */
109 };
110 
111 
112 static void *
113 ngx_mail_pop3_create_srv_conf(ngx_conf_t *cf)
114 {
116 
117  pscf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_pop3_srv_conf_t));
118  if (pscf == NULL) {
119  return NULL;
120  }
121 
122  if (ngx_array_init(&pscf->capabilities, cf->pool, 4, sizeof(ngx_str_t))
123  != NGX_OK)
124  {
125  return NULL;
126  }
127 
128  return pscf;
129 }
130 
131 
132 static char *
133 ngx_mail_pop3_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
134 {
135  ngx_mail_pop3_srv_conf_t *prev = parent;
136  ngx_mail_pop3_srv_conf_t *conf = child;
137 
138  u_char *p;
139  size_t size, stls_only_size;
140  ngx_str_t *c, *d;
141  ngx_uint_t i;
142 
144  prev->auth_methods,
147 
148  if (conf->capabilities.nelts == 0) {
149  conf->capabilities = prev->capabilities;
150  }
151 
152  if (conf->capabilities.nelts == 0) {
153 
154  for (d = ngx_mail_pop3_default_capabilities; d->len; d++) {
155  c = ngx_array_push(&conf->capabilities);
156  if (c == NULL) {
157  return NGX_CONF_ERROR;
158  }
159 
160  *c = *d;
161  }
162  }
163 
164  size = sizeof("+OK Capability list follows" CRLF) - 1
165  + sizeof("." CRLF) - 1;
166 
167  stls_only_size = size + sizeof("STLS" CRLF) - 1;
168 
169  c = conf->capabilities.elts;
170  for (i = 0; i < conf->capabilities.nelts; i++) {
171  size += c[i].len + sizeof(CRLF) - 1;
172 
173  if (ngx_strcasecmp(c[i].data, (u_char *) "USER") == 0) {
174  continue;
175  }
176 
177  stls_only_size += c[i].len + sizeof(CRLF) - 1;
178  }
179 
181  size += sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1;
182 
183  } else {
184  size += sizeof("SASL LOGIN PLAIN" CRLF) - 1;
185  }
186 
187  p = ngx_pnalloc(cf->pool, size);
188  if (p == NULL) {
189  return NGX_CONF_ERROR;
190  }
191 
192  conf->capability.len = size;
193  conf->capability.data = p;
194 
195  p = ngx_cpymem(p, "+OK Capability list follows" CRLF,
196  sizeof("+OK Capability list follows" CRLF) - 1);
197 
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;
201  }
202 
204  p = ngx_cpymem(p, "SASL LOGIN PLAIN CRAM-MD5" CRLF,
205  sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1);
206 
207  } else {
208  p = ngx_cpymem(p, "SASL LOGIN PLAIN" CRLF,
209  sizeof("SASL LOGIN PLAIN" CRLF) - 1);
210  }
211 
212  *p++ = '.'; *p++ = CR; *p = LF;
213 
214 
215  size += sizeof("STLS" CRLF) - 1;
216 
217  p = ngx_pnalloc(cf->pool, size);
218  if (p == NULL) {
219  return NGX_CONF_ERROR;
220  }
221 
222  conf->starttls_capability.len = size;
223  conf->starttls_capability.data = p;
224 
225  p = ngx_cpymem(p, conf->capability.data,
226  conf->capability.len - (sizeof("." CRLF) - 1));
227 
228  p = ngx_cpymem(p, "STLS" CRLF, sizeof("STLS" CRLF) - 1);
229  *p++ = '.'; *p++ = CR; *p = LF;
230 
231 
233  conf->auth_capability = ngx_mail_pop3_auth_cram_md5_capability;
234 
235  } else {
236  conf->auth_capability = ngx_mail_pop3_auth_plain_capability;
237  }
238 
239 
240  p = ngx_pnalloc(cf->pool, stls_only_size);
241  if (p == NULL) {
242  return NGX_CONF_ERROR;
243  }
244 
245  conf->starttls_only_capability.len = stls_only_size;
246  conf->starttls_only_capability.data = p;
247 
248  p = ngx_cpymem(p, "+OK Capability list follows" CRLF,
249  sizeof("+OK Capability list follows" CRLF) - 1);
250 
251  for (i = 0; i < conf->capabilities.nelts; i++) {
252  if (ngx_strcasecmp(c[i].data, (u_char *) "USER") == 0) {
253  continue;
254  }
255 
256  p = ngx_cpymem(p, c[i].data, c[i].len);
257  *p++ = CR; *p++ = LF;
258  }
259 
260  p = ngx_cpymem(p, "STLS" CRLF, sizeof("STLS" CRLF) - 1);
261  *p++ = '.'; *p++ = CR; *p = LF;
262 
263  return NGX_CONF_OK;
264 }