~nginx/nginx/1.0

« back to all changes in this revision

Viewing changes to src/mail/ngx_mail_pop3_module.c

  • Committer: Michael Lustfield
  • Date: 2010-12-01 08:06:25 UTC
  • Revision ID: michael@profarius.com-20101201080625-y8i4bq0e54ev2qwy
Tags: 0.9.0
Nginx v0.9.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/*
 
3
 * Copyright (C) Igor Sysoev
 
4
 */
 
5
 
 
6
 
 
7
#include <ngx_config.h>
 
8
#include <ngx_core.h>
 
9
#include <ngx_event.h>
 
10
#include <ngx_mail.h>
 
11
#include <ngx_mail_pop3_module.h>
 
12
 
 
13
 
 
14
static void *ngx_mail_pop3_create_srv_conf(ngx_conf_t *cf);
 
15
static char *ngx_mail_pop3_merge_srv_conf(ngx_conf_t *cf, void *parent,
 
16
    void *child);
 
17
 
 
18
 
 
19
static ngx_str_t  ngx_mail_pop3_default_capabilities[] = {
 
20
    ngx_string("TOP"),
 
21
    ngx_string("USER"),
 
22
    ngx_string("UIDL"),
 
23
    ngx_null_string
 
24
};
 
25
 
 
26
 
 
27
static ngx_conf_bitmask_t  ngx_mail_pop3_auth_methods[] = {
 
28
    { ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED },
 
29
    { ngx_string("apop"), NGX_MAIL_AUTH_APOP_ENABLED },
 
30
    { ngx_string("cram-md5"), NGX_MAIL_AUTH_CRAM_MD5_ENABLED },
 
31
    { ngx_null_string, 0 }
 
32
};
 
33
 
 
34
 
 
35
static ngx_str_t  ngx_mail_pop3_auth_plain_capability =
 
36
    ngx_string("+OK methods supported:" CRLF
 
37
               "LOGIN" CRLF
 
38
               "PLAIN" CRLF
 
39
               "." CRLF);
 
40
 
 
41
 
 
42
static ngx_str_t  ngx_mail_pop3_auth_cram_md5_capability =
 
43
    ngx_string("+OK methods supported:" CRLF
 
44
               "LOGIN" CRLF
 
45
               "PLAIN" CRLF
 
46
               "CRAM-MD5" CRLF
 
47
               "." CRLF);
 
48
 
 
49
 
 
50
static ngx_mail_protocol_t  ngx_mail_pop3_protocol = {
 
51
    ngx_string("pop3"),
 
52
    { 110, 995, 0, 0 },
 
53
    NGX_MAIL_POP3_PROTOCOL,
 
54
 
 
55
    ngx_mail_pop3_init_session,
 
56
    ngx_mail_pop3_init_protocol,
 
57
    ngx_mail_pop3_parse_command,
 
58
    ngx_mail_pop3_auth_state,
 
59
 
 
60
    ngx_string("-ERR internal server error" CRLF)
 
61
};
 
62
 
 
63
 
 
64
static ngx_command_t  ngx_mail_pop3_commands[] = {
 
65
 
 
66
    { ngx_string("pop3_capabilities"),
 
67
      NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
 
68
      ngx_mail_capabilities,
 
69
      NGX_MAIL_SRV_CONF_OFFSET,
 
70
      offsetof(ngx_mail_pop3_srv_conf_t, capabilities),
 
71
      NULL },
 
72
 
 
73
    { ngx_string("pop3_auth"),
 
74
      NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
 
75
      ngx_conf_set_bitmask_slot,
 
76
      NGX_MAIL_SRV_CONF_OFFSET,
 
77
      offsetof(ngx_mail_pop3_srv_conf_t, auth_methods),
 
78
      &ngx_mail_pop3_auth_methods },
 
79
 
 
80
      ngx_null_command
 
81
};
 
82
 
 
83
 
 
84
static ngx_mail_module_t  ngx_mail_pop3_module_ctx = {
 
85
    &ngx_mail_pop3_protocol,               /* protocol */
 
86
 
 
87
    NULL,                                  /* create main configuration */
 
88
    NULL,                                  /* init main configuration */
 
89
 
 
90
    ngx_mail_pop3_create_srv_conf,         /* create server configuration */
 
91
    ngx_mail_pop3_merge_srv_conf           /* merge server configuration */
 
92
};
 
93
 
 
94
 
 
95
ngx_module_t  ngx_mail_pop3_module = {
 
96
    NGX_MODULE_V1,
 
97
    &ngx_mail_pop3_module_ctx,             /* module context */
 
98
    ngx_mail_pop3_commands,                /* module directives */
 
99
    NGX_MAIL_MODULE,                       /* module type */
 
100
    NULL,                                  /* init master */
 
101
    NULL,                                  /* init module */
 
102
    NULL,                                  /* init process */
 
103
    NULL,                                  /* init thread */
 
104
    NULL,                                  /* exit thread */
 
105
    NULL,                                  /* exit process */
 
106
    NULL,                                  /* exit master */
 
107
    NGX_MODULE_V1_PADDING
 
108
};
 
109
 
 
110
 
 
111
static void *
 
112
ngx_mail_pop3_create_srv_conf(ngx_conf_t *cf)
 
113
{
 
114
    ngx_mail_pop3_srv_conf_t  *pscf;
 
115
 
 
116
    pscf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_pop3_srv_conf_t));
 
117
    if (pscf == NULL) {
 
118
        return NULL;
 
119
    }
 
120
 
 
121
    if (ngx_array_init(&pscf->capabilities, cf->pool, 4, sizeof(ngx_str_t))
 
122
        != NGX_OK)
 
123
    {
 
124
        return NULL;
 
125
    }
 
126
 
 
127
    return pscf;
 
128
}
 
129
 
 
130
 
 
131
static char *
 
132
ngx_mail_pop3_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
 
133
{
 
134
    ngx_mail_pop3_srv_conf_t *prev = parent;
 
135
    ngx_mail_pop3_srv_conf_t *conf = child;
 
136
 
 
137
    u_char      *p;
 
138
    size_t       size, stls_only_size;
 
139
    ngx_str_t   *c, *d;
 
140
    ngx_uint_t   i;
 
141
 
 
142
    ngx_conf_merge_bitmask_value(conf->auth_methods,
 
143
                                 prev->auth_methods,
 
144
                                 (NGX_CONF_BITMASK_SET
 
145
                                  |NGX_MAIL_AUTH_PLAIN_ENABLED));
 
146
 
 
147
    if (conf->capabilities.nelts == 0) {
 
148
        conf->capabilities = prev->capabilities;
 
149
    }
 
150
 
 
151
    if (conf->capabilities.nelts == 0) {
 
152
 
 
153
        for (d = ngx_mail_pop3_default_capabilities; d->len; d++) {
 
154
            c = ngx_array_push(&conf->capabilities);
 
155
            if (c == NULL) {
 
156
                return NGX_CONF_ERROR;
 
157
            }
 
158
 
 
159
            *c = *d;
 
160
        }
 
161
    }
 
162
 
 
163
    size = sizeof("+OK Capability list follows" CRLF) - 1
 
164
           + sizeof("." CRLF) - 1;
 
165
 
 
166
    stls_only_size = size + sizeof("STLS" CRLF) - 1;
 
167
 
 
168
    c = conf->capabilities.elts;
 
169
    for (i = 0; i < conf->capabilities.nelts; i++) {
 
170
        size += c[i].len + sizeof(CRLF) - 1;
 
171
 
 
172
        if (ngx_strcasecmp(c[i].data, (u_char *) "USER") == 0) {
 
173
            continue;
 
174
        }
 
175
 
 
176
        stls_only_size += c[i].len + sizeof(CRLF) - 1;
 
177
    }
 
178
 
 
179
    if (conf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) {
 
180
        size += sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1;
 
181
 
 
182
    } else {
 
183
        size += sizeof("SASL LOGIN PLAIN" CRLF) - 1;
 
184
    }
 
185
 
 
186
    p = ngx_pnalloc(cf->pool, size);
 
187
    if (p == NULL) {
 
188
        return NGX_CONF_ERROR;
 
189
    }
 
190
 
 
191
    conf->capability.len = size;
 
192
    conf->capability.data = p;
 
193
 
 
194
    p = ngx_cpymem(p, "+OK Capability list follows" CRLF,
 
195
                   sizeof("+OK Capability list follows" CRLF) - 1);
 
196
 
 
197
    for (i = 0; i < conf->capabilities.nelts; i++) {
 
198
        p = ngx_cpymem(p, c[i].data, c[i].len);
 
199
        *p++ = CR; *p++ = LF;
 
200
    }
 
201
 
 
202
    if (conf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) {
 
203
        p = ngx_cpymem(p, "SASL LOGIN PLAIN CRAM-MD5" CRLF,
 
204
                       sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1);
 
205
 
 
206
    } else {
 
207
        p = ngx_cpymem(p, "SASL LOGIN PLAIN" CRLF,
 
208
                       sizeof("SASL LOGIN PLAIN" CRLF) - 1);
 
209
    }
 
210
 
 
211
    *p++ = '.'; *p++ = CR; *p = LF;
 
212
 
 
213
 
 
214
    size += sizeof("STLS" CRLF) - 1;
 
215
 
 
216
    p = ngx_pnalloc(cf->pool, size);
 
217
    if (p == NULL) {
 
218
        return NGX_CONF_ERROR;
 
219
    }
 
220
 
 
221
    conf->starttls_capability.len = size;
 
222
    conf->starttls_capability.data = p;
 
223
 
 
224
    p = ngx_cpymem(p, conf->capability.data,
 
225
                   conf->capability.len - (sizeof("." CRLF) - 1));
 
226
 
 
227
    p = ngx_cpymem(p, "STLS" CRLF, sizeof("STLS" CRLF) - 1);
 
228
    *p++ = '.'; *p++ = CR; *p = LF;
 
229
 
 
230
 
 
231
    if (conf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) {
 
232
        conf->auth_capability = ngx_mail_pop3_auth_cram_md5_capability;
 
233
 
 
234
    } else {
 
235
        conf->auth_capability = ngx_mail_pop3_auth_plain_capability;
 
236
    }
 
237
 
 
238
 
 
239
    p = ngx_pnalloc(cf->pool, stls_only_size);
 
240
    if (p == NULL) {
 
241
        return NGX_CONF_ERROR;
 
242
    }
 
243
 
 
244
    conf->starttls_only_capability.len = stls_only_size;
 
245
    conf->starttls_only_capability.data = p;
 
246
 
 
247
    p = ngx_cpymem(p, "+OK Capability list follows" CRLF,
 
248
                   sizeof("+OK Capability list follows" CRLF) - 1);
 
249
 
 
250
    for (i = 0; i < conf->capabilities.nelts; i++) {
 
251
        if (ngx_strcasecmp(c[i].data, (u_char *) "USER") == 0) {
 
252
            continue;
 
253
        }
 
254
 
 
255
        p = ngx_cpymem(p, c[i].data, c[i].len);
 
256
        *p++ = CR; *p++ = LF;
 
257
    }
 
258
 
 
259
    p = ngx_cpymem(p, "STLS" CRLF, sizeof("STLS" CRLF) - 1);
 
260
    *p++ = '.'; *p++ = CR; *p = LF;
 
261
 
 
262
    return NGX_CONF_OK;
 
263
}