Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ngx_mail_imap_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_imap_module.h>
13 
14 
15 static void *ngx_mail_imap_create_srv_conf(ngx_conf_t *cf);
16 static char *ngx_mail_imap_merge_srv_conf(ngx_conf_t *cf, void *parent,
17  void *child);
18 
19 
20 static ngx_str_t ngx_mail_imap_default_capabilities[] = {
21  ngx_string("IMAP4"),
22  ngx_string("IMAP4rev1"),
23  ngx_string("UIDPLUS"),
25 };
26 
27 
28 static ngx_conf_bitmask_t ngx_mail_imap_auth_methods[] = {
32  { ngx_null_string, 0 }
33 };
34 
35 
36 static ngx_str_t ngx_mail_imap_auth_methods_names[] = {
37  ngx_string("AUTH=PLAIN"),
38  ngx_string("AUTH=LOGIN"),
39  ngx_null_string, /* APOP */
40  ngx_string("AUTH=CRAM-MD5"),
41  ngx_null_string /* NONE */
42 };
43 
44 
45 static ngx_mail_protocol_t ngx_mail_imap_protocol = {
46  ngx_string("imap"),
47  { 143, 993, 0, 0 },
49 
54 
55  ngx_string("* BAD internal server error" CRLF)
56 };
57 
58 
59 static ngx_command_t ngx_mail_imap_commands[] = {
60 
61  { ngx_string("imap_client_buffer"),
65  offsetof(ngx_mail_imap_srv_conf_t, client_buffer_size),
66  NULL },
67 
68  { ngx_string("imap_capabilities"),
72  offsetof(ngx_mail_imap_srv_conf_t, capabilities),
73  NULL },
74 
75  { ngx_string("imap_auth"),
79  offsetof(ngx_mail_imap_srv_conf_t, auth_methods),
80  &ngx_mail_imap_auth_methods },
81 
83 };
84 
85 
86 static ngx_mail_module_t ngx_mail_imap_module_ctx = {
87  &ngx_mail_imap_protocol, /* protocol */
88 
89  NULL, /* create main configuration */
90  NULL, /* init main configuration */
91 
92  ngx_mail_imap_create_srv_conf, /* create server configuration */
93  ngx_mail_imap_merge_srv_conf /* merge server configuration */
94 };
95 
96 
99  &ngx_mail_imap_module_ctx, /* module context */
100  ngx_mail_imap_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 */
110 };
111 
112 
113 static void *
114 ngx_mail_imap_create_srv_conf(ngx_conf_t *cf)
115 {
117 
118  iscf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_imap_srv_conf_t));
119  if (iscf == NULL) {
120  return NULL;
121  }
122 
124 
125  if (ngx_array_init(&iscf->capabilities, cf->pool, 4, sizeof(ngx_str_t))
126  != NGX_OK)
127  {
128  return NULL;
129  }
130 
131  return iscf;
132 }
133 
134 
135 static char *
136 ngx_mail_imap_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
137 {
138  ngx_mail_imap_srv_conf_t *prev = parent;
139  ngx_mail_imap_srv_conf_t *conf = child;
140 
141  u_char *p, *auth;
142  size_t size;
143  ngx_str_t *c, *d;
144  ngx_uint_t i, m;
145 
147  prev->client_buffer_size,
148  (size_t) ngx_pagesize);
149 
151  prev->auth_methods,
154 
155 
156  if (conf->capabilities.nelts == 0) {
157  conf->capabilities = prev->capabilities;
158  }
159 
160  if (conf->capabilities.nelts == 0) {
161 
162  for (d = ngx_mail_imap_default_capabilities; d->len; d++) {
163  c = ngx_array_push(&conf->capabilities);
164  if (c == NULL) {
165  return NGX_CONF_ERROR;
166  }
167 
168  *c = *d;
169  }
170  }
171 
172  size = sizeof("* CAPABILITY" CRLF) - 1;
173 
174  c = conf->capabilities.elts;
175  for (i = 0; i < conf->capabilities.nelts; i++) {
176  size += 1 + c[i].len;
177  }
178 
179  for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
181  m <<= 1, i++)
182  {
183  if (m & conf->auth_methods) {
184  size += 1 + ngx_mail_imap_auth_methods_names[i].len;
185  }
186  }
187 
188  p = ngx_pnalloc(cf->pool, size);
189  if (p == NULL) {
190  return NGX_CONF_ERROR;
191  }
192 
193  conf->capability.len = size;
194  conf->capability.data = p;
195 
196  p = ngx_cpymem(p, "* CAPABILITY", sizeof("* CAPABILITY") - 1);
197 
198  for (i = 0; i < conf->capabilities.nelts; i++) {
199  *p++ = ' ';
200  p = ngx_cpymem(p, c[i].data, c[i].len);
201  }
202 
203  auth = p;
204 
205  for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
207  m <<= 1, i++)
208  {
209  if (m & conf->auth_methods) {
210  *p++ = ' ';
211  p = ngx_cpymem(p, ngx_mail_imap_auth_methods_names[i].data,
212  ngx_mail_imap_auth_methods_names[i].len);
213  }
214  }
215 
216  *p++ = CR; *p = LF;
217 
218 
219  size += sizeof(" STARTTLS") - 1;
220 
221  p = ngx_pnalloc(cf->pool, size);
222  if (p == NULL) {
223  return NGX_CONF_ERROR;
224  }
225 
226  conf->starttls_capability.len = size;
227  conf->starttls_capability.data = p;
228 
229  p = ngx_cpymem(p, conf->capability.data,
230  conf->capability.len - (sizeof(CRLF) - 1));
231  p = ngx_cpymem(p, " STARTTLS", sizeof(" STARTTLS") - 1);
232  *p++ = CR; *p = LF;
233 
234 
235  size = (auth - conf->capability.data) + sizeof(CRLF) - 1
236  + sizeof(" STARTTLS LOGINDISABLED") - 1;
237 
238  p = ngx_pnalloc(cf->pool, size);
239  if (p == NULL) {
240  return NGX_CONF_ERROR;
241  }
242 
243  conf->starttls_only_capability.len = size;
244  conf->starttls_only_capability.data = p;
245 
246  p = ngx_cpymem(p, conf->capability.data,
247  auth - conf->capability.data);
248  p = ngx_cpymem(p, " STARTTLS LOGINDISABLED",
249  sizeof(" STARTTLS LOGINDISABLED") - 1);
250  *p++ = CR; *p = LF;
251 
252  return NGX_CONF_OK;
253 }