Back to home page

Nginx displayed by LXR

Source navigation ]
Diff markup ]
Identifier search ]
general search ]
 
 
Version: nginx-1.15.12 ]​[ nginx-1.16.0 ]​

0001 
0002 /*
0003  * Copyright (C) Igor Sysoev
0004  * Copyright (C) Nginx, Inc.
0005  */
0006 
0007 
0008 #include <ngx_config.h>
0009 #include <ngx_core.h>
0010 #include <ngx_event.h>
0011 #include <ngx_mail.h>
0012 #include <ngx_mail_pop3_module.h>
0013 
0014 
0015 static void *ngx_mail_pop3_create_srv_conf(ngx_conf_t *cf);
0016 static char *ngx_mail_pop3_merge_srv_conf(ngx_conf_t *cf, void *parent,
0017     void *child);
0018 
0019 
0020 static ngx_str_t  ngx_mail_pop3_default_capabilities[] = {
0021     ngx_string("TOP"),
0022     ngx_string("USER"),
0023     ngx_string("UIDL"),
0024     ngx_null_string
0025 };
0026 
0027 
0028 static ngx_conf_bitmask_t  ngx_mail_pop3_auth_methods[] = {
0029     { ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED },
0030     { ngx_string("apop"), NGX_MAIL_AUTH_APOP_ENABLED },
0031     { ngx_string("cram-md5"), NGX_MAIL_AUTH_CRAM_MD5_ENABLED },
0032     { ngx_string("external"), NGX_MAIL_AUTH_EXTERNAL_ENABLED },
0033     { ngx_null_string, 0 }
0034 };
0035 
0036 
0037 static ngx_str_t  ngx_mail_pop3_auth_methods_names[] = {
0038     ngx_string("PLAIN"),
0039     ngx_string("LOGIN"),
0040     ngx_null_string,  /* APOP */
0041     ngx_string("CRAM-MD5"),
0042     ngx_string("EXTERNAL"),
0043     ngx_null_string   /* NONE */
0044 };
0045 
0046 
0047 static ngx_mail_protocol_t  ngx_mail_pop3_protocol = {
0048     ngx_string("pop3"),
0049     { 110, 995, 0, 0 },
0050     NGX_MAIL_POP3_PROTOCOL,
0051 
0052     ngx_mail_pop3_init_session,
0053     ngx_mail_pop3_init_protocol,
0054     ngx_mail_pop3_parse_command,
0055     ngx_mail_pop3_auth_state,
0056 
0057     ngx_string("-ERR internal server error" CRLF),
0058     ngx_string("-ERR SSL certificate error" CRLF),
0059     ngx_string("-ERR No required SSL certificate" CRLF)
0060 };
0061 
0062 
0063 static ngx_command_t  ngx_mail_pop3_commands[] = {
0064 
0065     { ngx_string("pop3_capabilities"),
0066       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
0067       ngx_mail_capabilities,
0068       NGX_MAIL_SRV_CONF_OFFSET,
0069       offsetof(ngx_mail_pop3_srv_conf_t, capabilities),
0070       NULL },
0071 
0072     { ngx_string("pop3_auth"),
0073       NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
0074       ngx_conf_set_bitmask_slot,
0075       NGX_MAIL_SRV_CONF_OFFSET,
0076       offsetof(ngx_mail_pop3_srv_conf_t, auth_methods),
0077       &ngx_mail_pop3_auth_methods },
0078 
0079       ngx_null_command
0080 };
0081 
0082 
0083 static ngx_mail_module_t  ngx_mail_pop3_module_ctx = {
0084     &ngx_mail_pop3_protocol,               /* protocol */
0085 
0086     NULL,                                  /* create main configuration */
0087     NULL,                                  /* init main configuration */
0088 
0089     ngx_mail_pop3_create_srv_conf,         /* create server configuration */
0090     ngx_mail_pop3_merge_srv_conf           /* merge server configuration */
0091 };
0092 
0093 
0094 ngx_module_t  ngx_mail_pop3_module = {
0095     NGX_MODULE_V1,
0096     &ngx_mail_pop3_module_ctx,             /* module context */
0097     ngx_mail_pop3_commands,                /* module directives */
0098     NGX_MAIL_MODULE,                       /* module type */
0099     NULL,                                  /* init master */
0100     NULL,                                  /* init module */
0101     NULL,                                  /* init process */
0102     NULL,                                  /* init thread */
0103     NULL,                                  /* exit thread */
0104     NULL,                                  /* exit process */
0105     NULL,                                  /* exit master */
0106     NGX_MODULE_V1_PADDING
0107 };
0108 
0109 
0110 static void *
0111 ngx_mail_pop3_create_srv_conf(ngx_conf_t *cf)
0112 {
0113     ngx_mail_pop3_srv_conf_t  *pscf;
0114 
0115     pscf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_pop3_srv_conf_t));
0116     if (pscf == NULL) {
0117         return NULL;
0118     }
0119 
0120     if (ngx_array_init(&pscf->capabilities, cf->pool, 4, sizeof(ngx_str_t))
0121         != NGX_OK)
0122     {
0123         return NULL;
0124     }
0125 
0126     return pscf;
0127 }
0128 
0129 
0130 static char *
0131 ngx_mail_pop3_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
0132 {
0133     ngx_mail_pop3_srv_conf_t *prev = parent;
0134     ngx_mail_pop3_srv_conf_t *conf = child;
0135 
0136     u_char      *p;
0137     size_t       size, stls_only_size;
0138     ngx_str_t   *c, *d;
0139     ngx_uint_t   i, m;
0140 
0141     ngx_conf_merge_bitmask_value(conf->auth_methods,
0142                                  prev->auth_methods,
0143                                  (NGX_CONF_BITMASK_SET
0144                                   |NGX_MAIL_AUTH_PLAIN_ENABLED));
0145 
0146     if (conf->auth_methods & NGX_MAIL_AUTH_PLAIN_ENABLED) {
0147         conf->auth_methods |= NGX_MAIL_AUTH_LOGIN_ENABLED;
0148     }
0149 
0150     if (conf->capabilities.nelts == 0) {
0151         conf->capabilities = prev->capabilities;
0152     }
0153 
0154     if (conf->capabilities.nelts == 0) {
0155 
0156         for (d = ngx_mail_pop3_default_capabilities; d->len; d++) {
0157             c = ngx_array_push(&conf->capabilities);
0158             if (c == NULL) {
0159                 return NGX_CONF_ERROR;
0160             }
0161 
0162             *c = *d;
0163         }
0164     }
0165 
0166     size = sizeof("+OK Capability list follows" CRLF) - 1
0167            + sizeof("." CRLF) - 1;
0168 
0169     stls_only_size = size + sizeof("STLS" CRLF) - 1;
0170 
0171     c = conf->capabilities.elts;
0172     for (i = 0; i < conf->capabilities.nelts; i++) {
0173         size += c[i].len + sizeof(CRLF) - 1;
0174 
0175         if (ngx_strcasecmp(c[i].data, (u_char *) "USER") == 0) {
0176             continue;
0177         }
0178 
0179         stls_only_size += c[i].len + sizeof(CRLF) - 1;
0180     }
0181 
0182     size += sizeof("SASL") - 1 + sizeof(CRLF) - 1;
0183 
0184     for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
0185          m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED;
0186          m <<= 1, i++)
0187     {
0188         if (ngx_mail_pop3_auth_methods_names[i].len == 0) {
0189             continue;
0190         }
0191 
0192         if (m & conf->auth_methods) {
0193             size += 1 + ngx_mail_pop3_auth_methods_names[i].len;
0194         }
0195     }
0196 
0197     p = ngx_pnalloc(cf->pool, size);
0198     if (p == NULL) {
0199         return NGX_CONF_ERROR;
0200     }
0201 
0202     conf->capability.len = size;
0203     conf->capability.data = p;
0204 
0205     p = ngx_cpymem(p, "+OK Capability list follows" CRLF,
0206                    sizeof("+OK Capability list follows" CRLF) - 1);
0207 
0208     for (i = 0; i < conf->capabilities.nelts; i++) {
0209         p = ngx_cpymem(p, c[i].data, c[i].len);
0210         *p++ = CR; *p++ = LF;
0211     }
0212 
0213     p = ngx_cpymem(p, "SASL", sizeof("SASL") - 1);
0214 
0215     for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
0216          m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED;
0217          m <<= 1, i++)
0218     {
0219         if (ngx_mail_pop3_auth_methods_names[i].len == 0) {
0220             continue;
0221         }
0222 
0223         if (m & conf->auth_methods) {
0224             *p++ = ' ';
0225             p = ngx_cpymem(p, ngx_mail_pop3_auth_methods_names[i].data,
0226                            ngx_mail_pop3_auth_methods_names[i].len);
0227         }
0228     }
0229 
0230     *p++ = CR; *p++ = LF;
0231 
0232     *p++ = '.'; *p++ = CR; *p = LF;
0233 
0234 
0235     size += sizeof("STLS" CRLF) - 1;
0236 
0237     p = ngx_pnalloc(cf->pool, size);
0238     if (p == NULL) {
0239         return NGX_CONF_ERROR;
0240     }
0241 
0242     conf->starttls_capability.len = size;
0243     conf->starttls_capability.data = p;
0244 
0245     p = ngx_cpymem(p, conf->capability.data,
0246                    conf->capability.len - (sizeof("." CRLF) - 1));
0247 
0248     p = ngx_cpymem(p, "STLS" CRLF, sizeof("STLS" CRLF) - 1);
0249     *p++ = '.'; *p++ = CR; *p = LF;
0250 
0251 
0252     size = sizeof("+OK methods supported:" CRLF) - 1
0253            + sizeof("." CRLF) - 1;
0254 
0255     for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
0256          m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED;
0257          m <<= 1, i++)
0258     {
0259         if (ngx_mail_pop3_auth_methods_names[i].len == 0) {
0260             continue;
0261         }
0262 
0263         if (m & conf->auth_methods) {
0264             size += ngx_mail_pop3_auth_methods_names[i].len
0265                     + sizeof(CRLF) - 1;
0266         }
0267     }
0268 
0269     p = ngx_pnalloc(cf->pool, size);
0270     if (p == NULL) {
0271         return NGX_CONF_ERROR;
0272     }
0273 
0274     conf->auth_capability.data = p;
0275     conf->auth_capability.len = size;
0276 
0277     p = ngx_cpymem(p, "+OK methods supported:" CRLF,
0278                    sizeof("+OK methods supported:" CRLF) - 1);
0279 
0280     for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
0281          m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED;
0282          m <<= 1, i++)
0283     {
0284         if (ngx_mail_pop3_auth_methods_names[i].len == 0) {
0285             continue;
0286         }
0287 
0288         if (m & conf->auth_methods) {
0289             p = ngx_cpymem(p, ngx_mail_pop3_auth_methods_names[i].data,
0290                            ngx_mail_pop3_auth_methods_names[i].len);
0291             *p++ = CR; *p++ = LF;
0292         }
0293     }
0294 
0295     *p++ = '.'; *p++ = CR; *p = LF;
0296 
0297 
0298     p = ngx_pnalloc(cf->pool, stls_only_size);
0299     if (p == NULL) {
0300         return NGX_CONF_ERROR;
0301     }
0302 
0303     conf->starttls_only_capability.len = stls_only_size;
0304     conf->starttls_only_capability.data = p;
0305 
0306     p = ngx_cpymem(p, "+OK Capability list follows" CRLF,
0307                    sizeof("+OK Capability list follows" CRLF) - 1);
0308 
0309     for (i = 0; i < conf->capabilities.nelts; i++) {
0310         if (ngx_strcasecmp(c[i].data, (u_char *) "USER") == 0) {
0311             continue;
0312         }
0313 
0314         p = ngx_cpymem(p, c[i].data, c[i].len);
0315         *p++ = CR; *p++ = LF;
0316     }
0317 
0318     p = ngx_cpymem(p, "STLS" CRLF, sizeof("STLS" CRLF) - 1);
0319     *p++ = '.'; *p++ = CR; *p = LF;
0320 
0321     return NGX_CONF_OK;
0322 }