Many changes:

*) rename imap to mail, sort pop3/imap functions
*) smtp auth support
*) pop3 starttls only
*) fix segfault if cram-md5 was used without apop
This commit is contained in:
Igor Sysoev 2007-03-19 13:36:56 +00:00
parent 4ddeff4956
commit 02c8d181a4
16 changed files with 3321 additions and 2182 deletions

View File

@ -6,7 +6,7 @@ mkdir -p $NGX_OBJS/src/core $NGX_OBJS/src/event $NGX_OBJS/src/event/modules \
$NGX_OBJS/src/os/unix $NGX_OBJS/src/os/win32 \
$NGX_OBJS/src/http $NGX_OBJS/src/http/modules \
$NGX_OBJS/src/http/modules/perl \
$NGX_OBJS/src/imap
$NGX_OBJS/src/mail
ngx_objs_dir=$NGX_OBJS$ngx_regex_dirsep
@ -41,7 +41,7 @@ fi
# ALL_INCS, required by the addons and by OpenWatcom C precompiled headers
ngx_incs=`echo $CORE_INCS $NGX_OBJS $HTTP_INCS $IMAP_INCS\
ngx_incs=`echo $CORE_INCS $NGX_OBJS $HTTP_INCS $MAIL_INCS\
| sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont$ngx_include_opt\1/g" \
-e "s/\//$ngx_regex_dirsep/g"`
@ -101,26 +101,26 @@ END
fi
# the imap dependences and include pathes
# the mail dependences and include pathes
if [ $IMAP = YES ]; then
if [ $MAIL = YES ]; then
ngx_all_srcs="$ngx_all_srcs $IMAP_SRCS"
ngx_all_srcs="$ngx_all_srcs $MAIL_SRCS"
ngx_deps=`echo $IMAP_DEPS \
ngx_deps=`echo $MAIL_DEPS \
| sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont\1/g" \
-e "s/\//$ngx_regex_dirsep/g"`
ngx_incs=`echo $IMAP_INCS \
ngx_incs=`echo $MAIL_INCS \
| sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont$ngx_include_opt\1/g" \
-e "s/\//$ngx_regex_dirsep/g"`
cat << END >> $NGX_MAKEFILE
IMAP_DEPS = $ngx_deps
MAIL_DEPS = $ngx_deps
IMAP_INCS = $ngx_include_opt$ngx_incs
MAIL_INCS = $ngx_include_opt$ngx_incs
END
@ -279,17 +279,17 @@ END
fi
# the imap sources
# the mail sources
if [ $IMAP = YES ]; then
if [ $MAIL = YES ]; then
if test -n "$NGX_PCH"; then
ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)"
else
ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) \$(CORE_INCS) \$(IMAP_INCS)"
ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) \$(CORE_INCS) \$(MAIL_INCS)"
fi
for ngx_src in $IMAP_SRCS
for ngx_src in $MAIL_SRCS
do
ngx_src=`echo $ngx_src | sed -e "s/\//$ngx_regex_dirsep/g"`
ngx_obj=`echo $ngx_src \
@ -300,7 +300,7 @@ if [ $IMAP = YES ]; then
cat << END >> $NGX_MAKEFILE
$ngx_obj: \$(CORE_DEPS) \$(IMAP_DEPS)$ngx_cont$ngx_src
$ngx_obj: \$(CORE_DEPS) \$(MAIL_DEPS)$ngx_cont$ngx_src
$ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX
END

View File

@ -302,10 +302,10 @@ if test -n "$NGX_ADDONS"; then
fi
if [ $IMAP_SSL = YES ]; then
IMAP_DEPS="$IMAP_DEPS $IMAP_SSL_DEPS"
IMAP_SRCS="$IMAP_SRCS $IMAP_SSL_SRCS"
have=NGX_IMAP_SSL . auto/have
if [ $MAIL_SSL = YES ]; then
MAIL_DEPS="$MAIL_DEPS $MAIL_SSL_DEPS"
MAIL_SRCS="$MAIL_SRCS $MAIL_SSL_SRCS"
have=NGX_MAIL_SSL . auto/have
USE_OPENSSL=YES
fi
@ -331,18 +331,18 @@ if [ $HTTP = YES ]; then
fi
if [ $IMAP = YES ]; then
modules="$modules $IMAP_MODULES"
if [ $MAIL = YES ]; then
modules="$modules $MAIL_MODULES"
if [ $IMAP_SSL = YES ]; then
modules="$modules $IMAP_SSL_MODULE"
if [ $MAIL_SSL = YES ]; then
modules="$modules $MAIL_SSL_MODULE"
fi
modules="$modules $IMAP_AUTH_HTTP_MODULE"
IMAP_SRCS="$IMAP_SRCS $IMAP_AUTH_HTTP_SRCS"
modules="$modules $MAIL_AUTH_HTTP_MODULE"
MAIL_SRCS="$MAIL_SRCS $MAIL_AUTH_HTTP_SRCS"
modules="$modules $IMAP_PROXY_MODULE"
IMAP_SRCS="$IMAP_SRCS $IMAP_PROXY_SRCS"
modules="$modules $MAIL_PROXY_MODULE"
MAIL_SRCS="$MAIL_SRCS $MAIL_PROXY_SRCS"
fi

View File

@ -77,8 +77,8 @@ HTTP_UPSTREAM_IP_HASH=YES
# STUB
HTTP_STUB_STATUS=NO
IMAP=NO
IMAP_SSL=NO
MAIL=NO
MAIL_SSL=NO
NGX_ADDONS=
@ -182,8 +182,11 @@ do
# STUB
--with-http_stub_status_module) HTTP_STUB_STATUS=YES ;;
--with-imap) IMAP=YES ;;
--with-imap_ssl_module) IMAP_SSL=YES ;;
--with-mail) MAIL=YES ;;
--with-mail_ssl_module) MAIL_SSL=YES ;;
# STUB
--with-imap) MAIL=YES ;;
--with-imap_ssl_module) MAIL_SSL=YES ;;
--add-module=*) NGX_ADDONS="$NGX_ADDONS $value" ;;
@ -292,8 +295,8 @@ cat << END
--without-http disable HTTP server
--with-imap enable IMAP4/POP3 proxy module
--with-imap_ssl_module enable ngx_imap_ssl_module
--with-mail enable IMAP4/POP3/SMTP proxy module
--with-mail_ssl_module enable ngx_mail_ssl_module
--with-cc=PATH set path to C compiler
--with-cpp=PATH set path to C preprocessor

View File

@ -408,23 +408,23 @@ HTTP_UPSTREAM_IP_HASH_MODULE=ngx_http_upstream_ip_hash_module
HTTP_UPSTREAM_IP_HASH_SRCS=src/http/modules/ngx_http_upstream_ip_hash_module.c
IMAP_INCS="src/imap"
MAIL_INCS="src/mail"
IMAP_DEPS="src/imap/ngx_imap.h"
MAIL_DEPS="src/mail/ngx_mail.h"
IMAP_MODULES="ngx_imap_module ngx_imap_core_module"
MAIL_MODULES="ngx_mail_module ngx_mail_core_module"
IMAP_SRCS="src/imap/ngx_imap.c \
src/imap/ngx_imap_core_module.c \
src/imap/ngx_imap_handler.c \
src/imap/ngx_imap_parse.c"
MAIL_SRCS="src/mail/ngx_mail.c \
src/mail/ngx_mail_core_module.c \
src/mail/ngx_mail_handler.c \
src/mail/ngx_mail_parse.c"
IMAP_SSL_MODULE="ngx_imap_ssl_module"
IMAP_SSL_DEPS="src/imap/ngx_imap_ssl_module.h"
IMAP_SSL_SRCS="src/imap/ngx_imap_ssl_module.c"
MAIL_SSL_MODULE="ngx_mail_ssl_module"
MAIL_SSL_DEPS="src/mail/ngx_mail_ssl_module.h"
MAIL_SSL_SRCS="src/mail/ngx_mail_ssl_module.c"
IMAP_AUTH_HTTP_MODULE="ngx_imap_auth_http_module"
IMAP_AUTH_HTTP_SRCS="src/imap/ngx_imap_auth_http_module.c"
MAIL_AUTH_HTTP_MODULE="ngx_mail_auth_http_module"
MAIL_AUTH_HTTP_SRCS="src/mail/ngx_mail_auth_http_module.c"
IMAP_PROXY_MODULE="ngx_imap_proxy_module"
IMAP_PROXY_SRCS="src/imap/ngx_imap_proxy_module.c"
MAIL_PROXY_MODULE="ngx_mail_proxy_module"
MAIL_PROXY_SRCS="src/mail/ngx_mail_proxy_module.c"

View File

@ -58,7 +58,7 @@ static const char *err_levels[] = {
static const char *debug_levels[] = {
"debug_core", "debug_alloc", "debug_mutex", "debug_event",
"debug_http", "debug_imap"
"debug_http", "debug_mail", "debug_mysql"
};

View File

@ -27,7 +27,7 @@
#define NGX_LOG_DEBUG_MUTEX 0x040
#define NGX_LOG_DEBUG_EVENT 0x080
#define NGX_LOG_DEBUG_HTTP 0x100
#define NGX_LOG_DEBUG_IMAP 0x200
#define NGX_LOG_DEBUG_MAIL 0x200
#define NGX_LOG_DEBUG_MYSQL 0x400
/*
@ -36,7 +36,7 @@
*/
#define NGX_LOG_DEBUG_FIRST NGX_LOG_DEBUG_CORE
#define NGX_LOG_DEBUG_LAST NGX_LOG_DEBUG_IMAP
#define NGX_LOG_DEBUG_LAST NGX_LOG_DEBUG_MYSQL
#define NGX_LOG_DEBUG_CONNECTION 0x80000000
#define NGX_LOG_DEBUG_ALL 0x7ffffff0

File diff suppressed because it is too large Load Diff

View File

@ -7,22 +7,29 @@
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_event.h>
#include <ngx_imap.h>
#include <ngx_mail.h>
static char *ngx_imap_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static int ngx_libc_cdecl ngx_imap_cmp_conf_in_addrs(const void *one,
static char *ngx_mail_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static int ngx_libc_cdecl ngx_mail_cmp_conf_in_addrs(const void *one,
const void *two);
ngx_uint_t ngx_imap_max_module;
ngx_uint_t ngx_mail_max_module;
static ngx_command_t ngx_imap_commands[] = {
static ngx_command_t ngx_mail_commands[] = {
{ ngx_string("mail"),
NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
ngx_mail_block,
0,
0,
NULL },
{ ngx_string("imap"),
NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
ngx_imap_block,
ngx_mail_block,
0,
0,
NULL },
@ -31,17 +38,17 @@ static ngx_command_t ngx_imap_commands[] = {
};
static ngx_core_module_t ngx_imap_module_ctx = {
ngx_string("imap"),
static ngx_core_module_t ngx_mail_module_ctx = {
ngx_string("mail"),
NULL,
NULL
};
ngx_module_t ngx_imap_module = {
ngx_module_t ngx_mail_module = {
NGX_MODULE_V1,
&ngx_imap_module_ctx, /* module context */
ngx_imap_commands, /* module directives */
&ngx_mail_module_ctx, /* module context */
ngx_mail_commands, /* module directives */
NGX_CORE_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
@ -55,7 +62,7 @@ ngx_module_t ngx_imap_module = {
static char *
ngx_imap_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_mail_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
char *rv;
u_char *text;
@ -64,51 +71,57 @@ ngx_imap_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_conf_t pcf;
ngx_array_t in_ports;
ngx_listening_t *ls;
ngx_imap_listen_t *imls;
ngx_imap_module_t *module;
ngx_imap_in_port_t *imip;
ngx_imap_conf_ctx_t *ctx;
ngx_imap_conf_in_port_t *in_port;
ngx_imap_conf_in_addr_t *in_addr;
ngx_imap_core_srv_conf_t **cscfp;
ngx_imap_core_main_conf_t *cmcf;
ngx_mail_listen_t *imls;
ngx_mail_module_t *module;
ngx_mail_in_port_t *imip;
ngx_mail_conf_ctx_t *ctx;
ngx_mail_conf_in_port_t *in_port;
ngx_mail_conf_in_addr_t *in_addr;
ngx_mail_core_srv_conf_t **cscfp;
ngx_mail_core_main_conf_t *cmcf;
/* the main imap context */
if (cmd->name.data[0] == 'i') {
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
"the \"imap\" directive is deprecated, "
"use the \"mail\" directive instead");
}
ctx = ngx_pcalloc(cf->pool, sizeof(ngx_imap_conf_ctx_t));
/* the main mail context */
ctx = ngx_pcalloc(cf->pool, sizeof(ngx_mail_conf_ctx_t));
if (ctx == NULL) {
return NGX_CONF_ERROR;
}
*(ngx_imap_conf_ctx_t **) conf = ctx;
*(ngx_mail_conf_ctx_t **) conf = ctx;
/* count the number of the http modules and set up their indices */
ngx_imap_max_module = 0;
ngx_mail_max_module = 0;
for (m = 0; ngx_modules[m]; m++) {
if (ngx_modules[m]->type != NGX_IMAP_MODULE) {
if (ngx_modules[m]->type != NGX_MAIL_MODULE) {
continue;
}
ngx_modules[m]->ctx_index = ngx_imap_max_module++;
ngx_modules[m]->ctx_index = ngx_mail_max_module++;
}
/* the imap main_conf context, it is the same in the all imap contexts */
/* the mail main_conf context, it is the same in the all mail contexts */
ctx->main_conf = ngx_pcalloc(cf->pool,
sizeof(void *) * ngx_imap_max_module);
sizeof(void *) * ngx_mail_max_module);
if (ctx->main_conf == NULL) {
return NGX_CONF_ERROR;
}
/*
* the imap null srv_conf context, it is used to merge
* the mail null srv_conf context, it is used to merge
* the server{}s' srv_conf's
*/
ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_imap_max_module);
ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_mail_max_module);
if (ctx->srv_conf == NULL) {
return NGX_CONF_ERROR;
}
@ -116,11 +129,11 @@ ngx_imap_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
/*
* create the main_conf's, the null srv_conf's, and the null loc_conf's
* of the all imap modules
* of the all mail modules
*/
for (m = 0; ngx_modules[m]; m++) {
if (ngx_modules[m]->type != NGX_IMAP_MODULE) {
if (ngx_modules[m]->type != NGX_MAIL_MODULE) {
continue;
}
@ -143,13 +156,13 @@ ngx_imap_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
/* parse inside the imap{} block */
/* parse inside the mail{} block */
pcf = *cf;
cf->ctx = ctx;
cf->module_type = NGX_IMAP_MODULE;
cf->cmd_type = NGX_IMAP_MAIN_CONF;
cf->module_type = NGX_MAIL_MODULE;
cf->cmd_type = NGX_MAIL_MAIN_CONF;
rv = ngx_conf_parse(cf, NULL);
if (rv != NGX_CONF_OK) {
@ -158,20 +171,20 @@ ngx_imap_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
/* init imap{} main_conf's, merge the server{}s' srv_conf's */
/* init mail{} main_conf's, merge the server{}s' srv_conf's */
cmcf = ctx->main_conf[ngx_imap_core_module.ctx_index];
cmcf = ctx->main_conf[ngx_mail_core_module.ctx_index];
cscfp = cmcf->servers.elts;
for (m = 0; ngx_modules[m]; m++) {
if (ngx_modules[m]->type != NGX_IMAP_MODULE) {
if (ngx_modules[m]->type != NGX_MAIL_MODULE) {
continue;
}
module = ngx_modules[m]->ctx;
mi = ngx_modules[m]->ctx_index;
/* init imap{} main_conf's */
/* init mail{} main_conf's */
if (module->init_main_conf) {
rv = module->init_main_conf(cf, ctx->main_conf[mi]);
@ -197,13 +210,13 @@ ngx_imap_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
}
/* imap{}'s cf->ctx was needed while the configuration merging */
/* mail{}'s cf->ctx was needed while the configuration merging */
*cf = pcf;
if (ngx_array_init(&in_ports, cf->temp_pool, 4,
sizeof(ngx_imap_conf_in_port_t))
sizeof(ngx_mail_conf_in_port_t))
!= NGX_OK)
{
return NGX_CONF_ERROR;
@ -231,7 +244,7 @@ ngx_imap_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
in_port->port = imls[l].port;
if (ngx_array_init(&in_port->addrs, cf->temp_pool, 2,
sizeof(ngx_imap_conf_in_addr_t))
sizeof(ngx_mail_conf_in_addr_t))
!= NGX_OK)
{
return NGX_CONF_ERROR;
@ -257,7 +270,7 @@ ngx_imap_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
for (p = 0; p < in_ports.nelts; p++) {
ngx_qsort(in_port[p].addrs.elts, (size_t) in_port[p].addrs.nelts,
sizeof(ngx_imap_conf_in_addr_t), ngx_imap_cmp_conf_in_addrs);
sizeof(ngx_mail_conf_in_addr_t), ngx_mail_cmp_conf_in_addrs);
in_addr = in_port[p].addrs.elts;
last = in_port[p].addrs.nelts;
@ -293,7 +306,7 @@ ngx_imap_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ls->sndbuf = -1;
ls->addr_ntop = 1;
ls->handler = ngx_imap_init_connection;
ls->handler = ngx_mail_init_connection;
ls->pool_size = 256;
/* STUB */
@ -302,7 +315,7 @@ ngx_imap_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ls->log.handler = ngx_accept_log_error;
/**/
imip = ngx_palloc(cf->pool, sizeof(ngx_imap_in_port_t));
imip = ngx_palloc(cf->pool, sizeof(ngx_mail_in_port_t));
if (imip == NULL) {
return NGX_CONF_ERROR;
}
@ -334,7 +347,7 @@ ngx_imap_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
#endif
imip->addrs = ngx_pcalloc(cf->pool,
imip->naddrs * sizeof(ngx_imap_in_addr_t));
imip->naddrs * sizeof(ngx_mail_in_addr_t));
if (imip->addrs == NULL) {
return NGX_CONF_ERROR;
}
@ -375,12 +388,12 @@ ngx_imap_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
static int ngx_libc_cdecl
ngx_imap_cmp_conf_in_addrs(const void *one, const void *two)
ngx_mail_cmp_conf_in_addrs(const void *one, const void *two)
{
ngx_imap_conf_in_addr_t *first, *second;
ngx_mail_conf_in_addr_t *first, *second;
first = (ngx_imap_conf_in_addr_t *) one;
second = (ngx_imap_conf_in_addr_t *) two;
first = (ngx_mail_conf_in_addr_t *) one;
second = (ngx_mail_conf_in_addr_t *) two;
if (first->addr == INADDR_ANY) {
/* the INADDR_ANY must be the last resort, shift it to the end */

View File

@ -4,8 +4,8 @@
*/
#ifndef _NGX_IMAP_H_INCLUDED_
#define _NGX_IMAP_H_INCLUDED_
#ifndef _NGX_MAIL_H_INCLUDED_
#define _NGX_MAIL_H_INCLUDED_
#include <ngx_config.h>
@ -13,8 +13,8 @@
#include <ngx_event.h>
#include <ngx_event_connect.h>
#if (NGX_IMAP_SSL)
#include <ngx_imap_ssl_module.h>
#if (NGX_MAIL_SSL)
#include <ngx_mail_ssl_module.h>
#endif
@ -22,7 +22,7 @@
typedef struct {
void **main_conf;
void **srv_conf;
} ngx_imap_conf_ctx_t;
} ngx_mail_conf_ctx_t;
typedef struct {
@ -31,46 +31,47 @@ typedef struct {
int family;
/* server ctx */
ngx_imap_conf_ctx_t *ctx;
ngx_mail_conf_ctx_t *ctx;
unsigned bind:1;
} ngx_imap_listen_t;
} ngx_mail_listen_t;
typedef struct {
in_addr_t addr;
ngx_imap_conf_ctx_t *ctx;
ngx_mail_conf_ctx_t *ctx;
ngx_str_t addr_text;
} ngx_imap_in_addr_t;
} ngx_mail_in_addr_t;
typedef struct {
ngx_imap_in_addr_t *addrs; /* array of ngx_imap_in_addr_t */
ngx_mail_in_addr_t *addrs; /* array of ngx_mail_in_addr_t */
ngx_uint_t naddrs;
} ngx_imap_in_port_t;
} ngx_mail_in_port_t;
typedef struct {
in_port_t port;
ngx_array_t addrs; /* array of ngx_imap_conf_in_addr_t */
} ngx_imap_conf_in_port_t;
ngx_array_t addrs; /* array of ngx_mail_conf_in_addr_t */
} ngx_mail_conf_in_port_t;
typedef struct {
in_addr_t addr;
ngx_imap_conf_ctx_t *ctx;
ngx_mail_conf_ctx_t *ctx;
unsigned bind:1;
} ngx_imap_conf_in_addr_t;
} ngx_mail_conf_in_addr_t;
typedef struct {
ngx_array_t servers; /* ngx_imap_core_srv_conf_t */
ngx_array_t listen; /* ngx_imap_listen_t */
} ngx_imap_core_main_conf_t;
ngx_array_t servers; /* ngx_mail_core_srv_conf_t */
ngx_array_t listen; /* ngx_mail_listen_t */
} ngx_mail_core_main_conf_t;
#define NGX_IMAP_POP3_PROTOCOL 0
#define NGX_IMAP_IMAP_PROTOCOL 1
#define NGX_MAIL_POP3_PROTOCOL 0
#define NGX_MAIL_IMAP_PROTOCOL 1
#define NGX_MAIL_SMTP_PROTOCOL 2
typedef struct {
ngx_msec_t timeout;
@ -83,22 +84,29 @@ typedef struct {
ngx_str_t pop3_capability;
ngx_str_t pop3_starttls_capability;
ngx_str_t pop3_starttls_only_capability;
ngx_str_t pop3_auth_capability;
ngx_str_t imap_capability;
ngx_str_t imap_starttls_capability;
ngx_str_t imap_starttls_only_capability;
ngx_str_t server_name;
ngx_str_t smtp_capability;
ngx_uint_t auth_methods;
ngx_str_t server_name;
ngx_str_t smtp_server_name;
ngx_str_t smtp_greeting;
ngx_uint_t pop3_auth_methods;
ngx_uint_t smtp_auth_methods;
ngx_array_t pop3_capabilities;
ngx_array_t imap_capabilities;
ngx_array_t smtp_capabilities;
/* server ctx */
ngx_imap_conf_ctx_t *ctx;
} ngx_imap_core_srv_conf_t;
ngx_mail_conf_ctx_t *ctx;
} ngx_mail_core_srv_conf_t;
typedef struct {
@ -108,15 +116,7 @@ typedef struct {
void *(*create_srv_conf)(ngx_conf_t *cf);
char *(*merge_srv_conf)(ngx_conf_t *cf, void *prev,
void *conf);
} ngx_imap_module_t;
typedef enum {
ngx_imap_start = 0,
ngx_imap_login,
ngx_imap_user,
ngx_imap_passwd
} ngx_imap_state_e;
} ngx_mail_module_t;
typedef enum {
@ -130,14 +130,34 @@ typedef enum {
} ngx_po3_state_e;
typedef enum {
ngx_imap_start = 0,
ngx_imap_login,
ngx_imap_user,
ngx_imap_passwd
} ngx_imap_state_e;
typedef enum {
ngx_smtp_start = 0,
ngx_smtp_auth_login_username,
ngx_smtp_auth_login_password,
ngx_smtp_auth_plain,
ngx_smtp_auth_cram_md5,
ngx_smtp_helo,
ngx_smtp_noxclient,
ngx_smtp_xclient
} ngx_smtp_state_e;
typedef struct {
ngx_peer_connection_t upstream;
ngx_buf_t *buffer;
} ngx_imap_proxy_ctx_t;
} ngx_mail_proxy_ctx_t;
typedef struct {
uint32_t signature; /* "IMAP" */
uint32_t signature; /* "MAIL" */
ngx_connection_t *connection;
@ -148,17 +168,18 @@ typedef struct {
void **main_conf;
void **srv_conf;
ngx_imap_proxy_ctx_t *proxy;
ngx_mail_proxy_ctx_t *proxy;
ngx_uint_t imap_state;
ngx_uint_t mail_state;
unsigned blocked:1;
unsigned quit:1;
unsigned protocol:1;
unsigned protocol:2;
unsigned quoted:1;
unsigned backslash:1;
unsigned no_sync_literal:1;
unsigned starttls:1;
unsigned esmtp:1;
unsigned auth_method:2;
unsigned auth_wait:1;
@ -170,26 +191,27 @@ typedef struct {
ngx_str_t tagged_line;
ngx_str_t *addr_text;
ngx_str_t smtp_helo;
ngx_uint_t command;
ngx_array_t args;
ngx_uint_t login_attempt;
/* used to parse IMAP/POP3 command */
/* used to parse IMAP/POP3/SMTP command */
ngx_uint_t state;
u_char *cmd_start;
u_char *arg_start;
u_char *arg_end;
ngx_uint_t literal_len;
} ngx_imap_session_t;
} ngx_mail_session_t;
typedef struct {
ngx_str_t *client;
ngx_imap_session_t *session;
} ngx_imap_log_ctx_t;
ngx_mail_session_t *session;
} ngx_mail_log_ctx_t;
#define NGX_POP3_USER 1
@ -218,61 +240,74 @@ typedef struct {
#define NGX_IMAP_NEXT 6
#define NGX_IMAP_AUTH_PLAIN 0
#define NGX_IMAP_AUTH_APOP 1
#define NGX_IMAP_AUTH_CRAM_MD5 2
#define NGX_SMTP_HELO 1
#define NGX_SMTP_EHLO 2
#define NGX_SMTP_AUTH 3
#define NGX_SMTP_QUIT 4
#define NGX_SMTP_NOOP 5
#define NGX_SMTP_MAIL 6
#define NGX_SMTP_RSET 7
#define NGX_IMAP_AUTH_PLAIN_ENABLED 0x0002
#define NGX_IMAP_AUTH_APOP_ENABLED 0x0004
#define NGX_IMAP_AUTH_CRAM_MD5_ENABLED 0x0008
#define NGX_MAIL_AUTH_PLAIN 0
#define NGX_MAIL_AUTH_LOGIN 1
#define NGX_MAIL_AUTH_APOP 2
#define NGX_MAIL_AUTH_CRAM_MD5 3
#define NGX_IMAP_PARSE_INVALID_COMMAND 20
#define NGX_MAIL_AUTH_PLAIN_ENABLED 0x0002
#define NGX_MAIL_AUTH_LOGIN_ENABLED 0x0004
#define NGX_MAIL_AUTH_APOP_ENABLED 0x0008
#define NGX_MAIL_AUTH_CRAM_MD5_ENABLED 0x0010
#define NGX_IMAP_MODULE 0x50414D49 /* "IMAP" */
#define NGX_IMAP_MAIN_CONF 0x02000000
#define NGX_IMAP_SRV_CONF 0x04000000
#define NGX_MAIL_PARSE_INVALID_COMMAND 20
#define NGX_IMAP_MAIN_CONF_OFFSET offsetof(ngx_imap_conf_ctx_t, main_conf)
#define NGX_IMAP_SRV_CONF_OFFSET offsetof(ngx_imap_conf_ctx_t, srv_conf)
#define NGX_MAIL_MODULE 0x4C49414D /* "MAIL" */
#define NGX_MAIL_MAIN_CONF 0x02000000
#define NGX_MAIL_SRV_CONF 0x04000000
#define ngx_imap_get_module_ctx(s, module) (s)->ctx[module.ctx_index]
#define ngx_imap_set_ctx(s, c, module) s->ctx[module.ctx_index] = c;
#define ngx_imap_delete_ctx(s, module) s->ctx[module.ctx_index] = NULL;
#define NGX_MAIL_MAIN_CONF_OFFSET offsetof(ngx_mail_conf_ctx_t, main_conf)
#define NGX_MAIL_SRV_CONF_OFFSET offsetof(ngx_mail_conf_ctx_t, srv_conf)
#define ngx_imap_get_module_main_conf(s, module) \
#define ngx_mail_get_module_ctx(s, module) (s)->ctx[module.ctx_index]
#define ngx_mail_set_ctx(s, c, module) s->ctx[module.ctx_index] = c;
#define ngx_mail_delete_ctx(s, module) s->ctx[module.ctx_index] = NULL;
#define ngx_mail_get_module_main_conf(s, module) \
(s)->main_conf[module.ctx_index]
#define ngx_imap_get_module_srv_conf(s, module) (s)->srv_conf[module.ctx_index]
#define ngx_mail_get_module_srv_conf(s, module) (s)->srv_conf[module.ctx_index]
#define ngx_imap_conf_get_module_main_conf(cf, module) \
((ngx_imap_conf_ctx_t *) cf->ctx)->main_conf[module.ctx_index]
#define ngx_mail_conf_get_module_main_conf(cf, module) \
((ngx_mail_conf_ctx_t *) cf->ctx)->main_conf[module.ctx_index]
void ngx_imap_init_connection(ngx_connection_t *c);
void ngx_imap_send(ngx_event_t *wev);
void ngx_imap_auth_state(ngx_event_t *rev);
void ngx_mail_init_connection(ngx_connection_t *c);
void ngx_mail_send(ngx_event_t *wev);
void ngx_pop3_auth_state(ngx_event_t *rev);
void ngx_imap_close_connection(ngx_connection_t *c);
void ngx_imap_session_internal_server_error(ngx_imap_session_t *s);
void ngx_imap_auth_state(ngx_event_t *rev);
void ngx_smtp_auth_state(ngx_event_t *rev);
void ngx_mail_close_connection(ngx_connection_t *c);
void ngx_mail_session_internal_server_error(ngx_mail_session_t *s);
ngx_int_t ngx_imap_parse_command(ngx_imap_session_t *s);
ngx_int_t ngx_pop3_parse_command(ngx_imap_session_t *s);
ngx_int_t ngx_pop3_parse_command(ngx_mail_session_t *s);
ngx_int_t ngx_imap_parse_command(ngx_mail_session_t *s);
ngx_int_t ngx_smtp_parse_command(ngx_mail_session_t *s);
/* STUB */
void ngx_imap_proxy_init(ngx_imap_session_t *s, ngx_peer_addr_t *peer);
void ngx_imap_auth_http_init(ngx_imap_session_t *s);
void ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_peer_addr_t *peer);
void ngx_mail_auth_http_init(ngx_mail_session_t *s);
/**/
extern ngx_uint_t ngx_imap_max_module;
extern ngx_module_t ngx_imap_core_module;
extern ngx_uint_t ngx_mail_max_module;
extern ngx_module_t ngx_mail_core_module;
#endif /* _NGX_IMAP_H_INCLUDED_ */
#endif /* _NGX_MAIL_H_INCLUDED_ */

View File

@ -8,7 +8,7 @@
#include <ngx_core.h>
#include <ngx_event.h>
#include <ngx_event_connect.h>
#include <ngx_imap.h>
#include <ngx_mail.h>
typedef struct {
@ -21,20 +21,20 @@ typedef struct {
ngx_str_t header;
ngx_array_t *headers;
} ngx_imap_auth_http_conf_t;
} ngx_mail_auth_http_conf_t;
typedef struct ngx_imap_auth_http_ctx_s ngx_imap_auth_http_ctx_t;
typedef struct ngx_mail_auth_http_ctx_s ngx_mail_auth_http_ctx_t;
typedef void (*ngx_imap_auth_http_handler_pt)(ngx_imap_session_t *s,
ngx_imap_auth_http_ctx_t *ctx);
typedef void (*ngx_mail_auth_http_handler_pt)(ngx_mail_session_t *s,
ngx_mail_auth_http_ctx_t *ctx);
struct ngx_imap_auth_http_ctx_s {
struct ngx_mail_auth_http_ctx_s {
ngx_buf_t *request;
ngx_buf_t *response;
ngx_peer_connection_t peer;
ngx_imap_auth_http_handler_pt handler;
ngx_mail_auth_http_handler_pt handler;
ngx_uint_t state;
ngx_uint_t hash; /* no needed ? */
@ -48,6 +48,7 @@ struct ngx_imap_auth_http_ctx_s {
ngx_str_t port;
ngx_str_t err;
ngx_str_t errmsg;
ngx_str_t errcode;
time_t sleep;
@ -55,50 +56,50 @@ struct ngx_imap_auth_http_ctx_s {
};
static void ngx_imap_auth_http_write_handler(ngx_event_t *wev);
static void ngx_imap_auth_http_read_handler(ngx_event_t *rev);
static void ngx_imap_auth_http_ignore_status_line(ngx_imap_session_t *s,
ngx_imap_auth_http_ctx_t *ctx);
static void ngx_imap_auth_http_process_headers(ngx_imap_session_t *s,
ngx_imap_auth_http_ctx_t *ctx);
static void ngx_imap_auth_sleep_handler(ngx_event_t *rev);
static ngx_int_t ngx_imap_auth_http_parse_header_line(ngx_imap_session_t *s,
ngx_imap_auth_http_ctx_t *ctx);
static void ngx_imap_auth_http_block_read(ngx_event_t *rev);
static void ngx_imap_auth_http_dummy_handler(ngx_event_t *ev);
static ngx_buf_t *ngx_imap_auth_http_create_request(ngx_imap_session_t *s,
ngx_pool_t *pool, ngx_imap_auth_http_conf_t *ahcf);
static ngx_int_t ngx_imap_auth_http_escape(ngx_pool_t *pool, ngx_str_t *text,
static void ngx_mail_auth_http_write_handler(ngx_event_t *wev);
static void ngx_mail_auth_http_read_handler(ngx_event_t *rev);
static void ngx_mail_auth_http_ignore_status_line(ngx_mail_session_t *s,
ngx_mail_auth_http_ctx_t *ctx);
static void ngx_mail_auth_http_process_headers(ngx_mail_session_t *s,
ngx_mail_auth_http_ctx_t *ctx);
static void ngx_mail_auth_sleep_handler(ngx_event_t *rev);
static ngx_int_t ngx_mail_auth_http_parse_header_line(ngx_mail_session_t *s,
ngx_mail_auth_http_ctx_t *ctx);
static void ngx_mail_auth_http_block_read(ngx_event_t *rev);
static void ngx_mail_auth_http_dummy_handler(ngx_event_t *ev);
static ngx_buf_t *ngx_mail_auth_http_create_request(ngx_mail_session_t *s,
ngx_pool_t *pool, ngx_mail_auth_http_conf_t *ahcf);
static ngx_int_t ngx_mail_auth_http_escape(ngx_pool_t *pool, ngx_str_t *text,
ngx_str_t *escaped);
static void *ngx_imap_auth_http_create_conf(ngx_conf_t *cf);
static char *ngx_imap_auth_http_merge_conf(ngx_conf_t *cf, void *parent,
static void *ngx_mail_auth_http_create_conf(ngx_conf_t *cf);
static char *ngx_mail_auth_http_merge_conf(ngx_conf_t *cf, void *parent,
void *child);
static char *ngx_imap_auth_http(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static char *ngx_imap_auth_http_header(ngx_conf_t *cf, ngx_command_t *cmd,
static char *ngx_mail_auth_http(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static char *ngx_mail_auth_http_header(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static ngx_command_t ngx_imap_auth_http_commands[] = {
static ngx_command_t ngx_mail_auth_http_commands[] = {
{ ngx_string("auth_http"),
NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_TAKE1,
ngx_imap_auth_http,
NGX_IMAP_SRV_CONF_OFFSET,
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
ngx_mail_auth_http,
NGX_MAIL_SRV_CONF_OFFSET,
0,
NULL },
{ ngx_string("auth_http_timeout"),
NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_TAKE1,
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
ngx_conf_set_msec_slot,
NGX_IMAP_SRV_CONF_OFFSET,
offsetof(ngx_imap_auth_http_conf_t, timeout),
NGX_MAIL_SRV_CONF_OFFSET,
offsetof(ngx_mail_auth_http_conf_t, timeout),
NULL },
{ ngx_string("auth_http_header"),
NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_TAKE2,
ngx_imap_auth_http_header,
NGX_IMAP_SRV_CONF_OFFSET,
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE2,
ngx_mail_auth_http_header,
NGX_MAIL_SRV_CONF_OFFSET,
0,
NULL },
@ -106,20 +107,20 @@ static ngx_command_t ngx_imap_auth_http_commands[] = {
};
static ngx_imap_module_t ngx_imap_auth_http_module_ctx = {
static ngx_mail_module_t ngx_mail_auth_http_module_ctx = {
NULL, /* create main configuration */
NULL, /* init main configuration */
ngx_imap_auth_http_create_conf, /* create server configuration */
ngx_imap_auth_http_merge_conf /* merge server configuration */
ngx_mail_auth_http_create_conf, /* create server configuration */
ngx_mail_auth_http_merge_conf /* merge server configuration */
};
ngx_module_t ngx_imap_auth_http_module = {
ngx_module_t ngx_mail_auth_http_module = {
NGX_MODULE_V1,
&ngx_imap_auth_http_module_ctx, /* module context */
ngx_imap_auth_http_commands, /* module directives */
NGX_IMAP_MODULE, /* module type */
&ngx_mail_auth_http_module_ctx, /* module context */
ngx_mail_auth_http_commands, /* module directives */
NGX_MAIL_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
NULL, /* init process */
@ -131,49 +132,51 @@ ngx_module_t ngx_imap_auth_http_module = {
};
static char *ngx_imap_auth_http_protocol[] = { "pop3", "imap" };
static ngx_str_t ngx_imap_auth_http_method[] = {
static char *ngx_mail_auth_http_protocol[] = { "pop3", "imap", "smtp" };
static ngx_str_t ngx_mail_auth_http_method[] = {
ngx_string("plain"),
ngx_string("plain"),
ngx_string("apop"),
ngx_string("cram-md5")
};
static ngx_str_t ngx_mail_smtp_errcode = ngx_string("535 5.7.0");
void
ngx_imap_auth_http_init(ngx_imap_session_t *s)
ngx_mail_auth_http_init(ngx_mail_session_t *s)
{
ngx_int_t rc;
ngx_pool_t *pool;
ngx_imap_auth_http_ctx_t *ctx;
ngx_imap_auth_http_conf_t *ahcf;
ngx_mail_auth_http_ctx_t *ctx;
ngx_mail_auth_http_conf_t *ahcf;
s->connection->log->action = "in http auth state";
pool = ngx_create_pool(2048, s->connection->log);
if (pool == NULL) {
ngx_imap_session_internal_server_error(s);
ngx_mail_session_internal_server_error(s);
return;
}
ctx = ngx_pcalloc(pool, sizeof(ngx_imap_auth_http_ctx_t));
ctx = ngx_pcalloc(pool, sizeof(ngx_mail_auth_http_ctx_t));
if (ctx == NULL) {
ngx_destroy_pool(pool);
ngx_imap_session_internal_server_error(s);
ngx_mail_session_internal_server_error(s);
return;
}
ctx->pool = pool;
ahcf = ngx_imap_get_module_srv_conf(s, ngx_imap_auth_http_module);
ahcf = ngx_mail_get_module_srv_conf(s, ngx_mail_auth_http_module);
ctx->request = ngx_imap_auth_http_create_request(s, pool, ahcf);
ctx->request = ngx_mail_auth_http_create_request(s, pool, ahcf);
if (ctx->request == NULL) {
ngx_destroy_pool(ctx->pool);
ngx_imap_session_internal_server_error(s);
ngx_mail_session_internal_server_error(s);
return;
}
ngx_imap_set_ctx(s, ctx, ngx_imap_auth_http_module);
ngx_mail_set_ctx(s, ctx, ngx_mail_auth_http_module);
ctx->peer.sockaddr = ahcf->peer->sockaddr;
ctx->peer.socklen = ahcf->peer->socklen;
@ -190,52 +193,52 @@ ngx_imap_auth_http_init(ngx_imap_session_t *s)
}
ngx_destroy_pool(ctx->pool);
ngx_imap_session_internal_server_error(s);
ngx_mail_session_internal_server_error(s);
return;
}
ctx->peer.connection->data = s;
ctx->peer.connection->pool = s->connection->pool;
s->connection->read->handler = ngx_imap_auth_http_block_read;
ctx->peer.connection->read->handler = ngx_imap_auth_http_read_handler;
ctx->peer.connection->write->handler = ngx_imap_auth_http_write_handler;
s->connection->read->handler = ngx_mail_auth_http_block_read;
ctx->peer.connection->read->handler = ngx_mail_auth_http_read_handler;
ctx->peer.connection->write->handler = ngx_mail_auth_http_write_handler;
ctx->handler = ngx_imap_auth_http_ignore_status_line;
ctx->handler = ngx_mail_auth_http_ignore_status_line;
ngx_add_timer(ctx->peer.connection->read, ahcf->timeout);
ngx_add_timer(ctx->peer.connection->write, ahcf->timeout);
if (rc == NGX_OK) {
ngx_imap_auth_http_write_handler(ctx->peer.connection->write);
ngx_mail_auth_http_write_handler(ctx->peer.connection->write);
return;
}
}
static void
ngx_imap_auth_http_write_handler(ngx_event_t *wev)
ngx_mail_auth_http_write_handler(ngx_event_t *wev)
{
ssize_t n, size;
ngx_connection_t *c;
ngx_imap_session_t *s;
ngx_imap_auth_http_ctx_t *ctx;
ngx_imap_auth_http_conf_t *ahcf;
ngx_mail_session_t *s;
ngx_mail_auth_http_ctx_t *ctx;
ngx_mail_auth_http_conf_t *ahcf;
c = wev->data;
s = c->data;
ctx = ngx_imap_get_module_ctx(s, ngx_imap_auth_http_module);
ctx = ngx_mail_get_module_ctx(s, ngx_mail_auth_http_module);
ngx_log_debug0(NGX_LOG_DEBUG_IMAP, wev->log, 0,
"imap auth http write handler");
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, wev->log, 0,
"mail auth http write handler");
if (wev->timedout) {
ngx_log_error(NGX_LOG_ERR, wev->log, NGX_ETIMEDOUT,
"auth http server %V timed out", ctx->peer.name);
ngx_close_connection(ctx->peer.connection);
ngx_destroy_pool(ctx->pool);
ngx_imap_session_internal_server_error(s);
ngx_mail_session_internal_server_error(s);
return;
}
@ -246,7 +249,7 @@ ngx_imap_auth_http_write_handler(ngx_event_t *wev)
if (n == NGX_ERROR) {
ngx_close_connection(ctx->peer.connection);
ngx_destroy_pool(ctx->pool);
ngx_imap_session_internal_server_error(s);
ngx_mail_session_internal_server_error(s);
return;
}
@ -254,7 +257,7 @@ ngx_imap_auth_http_write_handler(ngx_event_t *wev)
ctx->request->pos += n;
if (n == size) {
wev->handler = ngx_imap_auth_http_dummy_handler;
wev->handler = ngx_mail_auth_http_dummy_handler;
if (wev->timer_set) {
ngx_del_timer(wev);
@ -263,7 +266,7 @@ ngx_imap_auth_http_write_handler(ngx_event_t *wev)
if (ngx_handle_write_event(wev, 0) == NGX_ERROR) {
ngx_close_connection(ctx->peer.connection);
ngx_destroy_pool(ctx->pool);
ngx_imap_session_internal_server_error(s);
ngx_mail_session_internal_server_error(s);
}
return;
@ -271,34 +274,34 @@ ngx_imap_auth_http_write_handler(ngx_event_t *wev)
}
if (!wev->timer_set) {
ahcf = ngx_imap_get_module_srv_conf(s, ngx_imap_auth_http_module);
ahcf = ngx_mail_get_module_srv_conf(s, ngx_mail_auth_http_module);
ngx_add_timer(wev, ahcf->timeout);
}
}
static void
ngx_imap_auth_http_read_handler(ngx_event_t *rev)
ngx_mail_auth_http_read_handler(ngx_event_t *rev)
{
ssize_t n, size;
ngx_connection_t *c;
ngx_imap_session_t *s;
ngx_imap_auth_http_ctx_t *ctx;
ngx_mail_session_t *s;
ngx_mail_auth_http_ctx_t *ctx;
c = rev->data;
s = c->data;
ngx_log_debug0(NGX_LOG_DEBUG_IMAP, rev->log, 0,
"imap auth http read handler");
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0,
"mail auth http read handler");
ctx = ngx_imap_get_module_ctx(s, ngx_imap_auth_http_module);
ctx = ngx_mail_get_module_ctx(s, ngx_mail_auth_http_module);
if (rev->timedout) {
ngx_log_error(NGX_LOG_ERR, rev->log, NGX_ETIMEDOUT,
"auth http server %V timed out", ctx->peer.name);
ngx_close_connection(ctx->peer.connection);
ngx_destroy_pool(ctx->pool);
ngx_imap_session_internal_server_error(s);
ngx_mail_session_internal_server_error(s);
return;
}
@ -307,7 +310,7 @@ ngx_imap_auth_http_read_handler(ngx_event_t *rev)
if (ctx->response == NULL) {
ngx_close_connection(ctx->peer.connection);
ngx_destroy_pool(ctx->pool);
ngx_imap_session_internal_server_error(s);
ngx_mail_session_internal_server_error(s);
return;
}
}
@ -329,13 +332,13 @@ ngx_imap_auth_http_read_handler(ngx_event_t *rev)
ngx_close_connection(ctx->peer.connection);
ngx_destroy_pool(ctx->pool);
ngx_imap_session_internal_server_error(s);
ngx_mail_session_internal_server_error(s);
}
static void
ngx_imap_auth_http_ignore_status_line(ngx_imap_session_t *s,
ngx_imap_auth_http_ctx_t *ctx)
ngx_mail_auth_http_ignore_status_line(ngx_mail_session_t *s,
ngx_mail_auth_http_ctx_t *ctx)
{
u_char *p, ch;
enum {
@ -348,8 +351,8 @@ ngx_imap_auth_http_ignore_status_line(ngx_imap_session_t *s,
sw_almost_done
} state;
ngx_log_debug0(NGX_LOG_DEBUG_IMAP, s->connection->log, 0,
"imap auth http process status line");
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, s->connection->log, 0,
"mail auth http process status line");
state = ctx->state;
@ -417,7 +420,7 @@ ngx_imap_auth_http_ignore_status_line(ngx_imap_session_t *s,
ctx->peer.name);
ngx_close_connection(ctx->peer.connection);
ngx_destroy_pool(ctx->pool);
ngx_imap_session_internal_server_error(s);
ngx_mail_session_internal_server_error(s);
return;
}
}
@ -435,14 +438,14 @@ done:
ctx->response->pos = p + 1;
ctx->state = 0;
ctx->handler = ngx_imap_auth_http_process_headers;
ctx->handler = ngx_mail_auth_http_process_headers;
ctx->handler(s, ctx);
}
static void
ngx_imap_auth_http_process_headers(ngx_imap_session_t *s,
ngx_imap_auth_http_ctx_t *ctx)
ngx_mail_auth_http_process_headers(ngx_mail_session_t *s,
ngx_mail_auth_http_ctx_t *ctx)
{
u_char *p;
time_t timer;
@ -451,11 +454,11 @@ ngx_imap_auth_http_process_headers(ngx_imap_session_t *s,
ngx_peer_addr_t *peer;
struct sockaddr_in *sin;
ngx_log_debug0(NGX_LOG_DEBUG_IMAP, s->connection->log, 0,
"imap auth http process headers");
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, s->connection->log, 0,
"mail auth http process headers");
for ( ;; ) {
rc = ngx_imap_auth_http_parse_header_line(s, ctx);
rc = ngx_mail_auth_http_parse_header_line(s, ctx);
if (rc == NGX_OK) {
@ -468,8 +471,8 @@ ngx_imap_auth_http_process_headers(ngx_imap_session_t *s,
value.len = ctx->header_end - ctx->header_start;
value.data = ctx->header_start;
ngx_log_debug2(NGX_LOG_DEBUG_IMAP, s->connection->log, 0,
"auth http header: \"%V: %V\"",
ngx_log_debug2(NGX_LOG_DEBUG_MAIL, s->connection->log, 0,
"mail auth http header: \"%V: %V\"",
&key, &value);
}
#endif
@ -504,33 +507,46 @@ ngx_imap_auth_http_process_headers(ngx_imap_session_t *s,
ctx->errmsg.len = len;
ctx->errmsg.data = ctx->header_start;
if (s->protocol == NGX_IMAP_POP3_PROTOCOL) {
size = sizeof("-ERR ") - 1 + len + sizeof(CRLF) - 1;
switch (s->protocol) {
} else {
case NGX_MAIL_POP3_PROTOCOL:
size = sizeof("-ERR ") - 1 + len + sizeof(CRLF) - 1;
break;
case NGX_MAIL_IMAP_PROTOCOL:
size = s->tag.len + sizeof("NO ") - 1 + len
+ sizeof(CRLF) - 1;
break;
default: /* NGX_MAIL_SMTP_PROTOCOL */
ctx->err = ctx->errmsg;
continue;
}
p = ngx_pcalloc(s->connection->pool, size);
if (p == NULL) {
ngx_close_connection(ctx->peer.connection);
ngx_destroy_pool(ctx->pool);
ngx_imap_session_internal_server_error(s);
ngx_mail_session_internal_server_error(s);
return;
}
ctx->err.data = p;
if (s->protocol == NGX_IMAP_POP3_PROTOCOL) {
*p++ = '-'; *p++ = 'E'; *p++ = 'R'; *p++ = 'R';
switch (s->protocol) {
} else {
case NGX_MAIL_POP3_PROTOCOL:
*p++ = '-'; *p++ = 'E'; *p++ = 'R'; *p++ = 'R'; *p++ = ' ';
break;
case NGX_MAIL_IMAP_PROTOCOL:
p = ngx_cpymem(p, s->tag.data, s->tag.len);
*p++ = 'N'; *p++ = 'O';
}
*p++ = 'N'; *p++ = 'O'; *p++ = ' ';
break;
*p++ = ' ';
default: /* NGX_MAIL_SMTP_PROTOCOL */
break;
}
p = ngx_cpymem(p, ctx->header_start, len);
*p++ = CR; *p++ = LF;
@ -576,7 +592,7 @@ ngx_imap_auth_http_process_headers(ngx_imap_session_t *s,
if (s->login.data == NULL) {
ngx_close_connection(ctx->peer.connection);
ngx_destroy_pool(ctx->pool);
ngx_imap_session_internal_server_error(s);
ngx_mail_session_internal_server_error(s);
return;
}
@ -597,7 +613,7 @@ ngx_imap_auth_http_process_headers(ngx_imap_session_t *s,
if (s->passwd.data == NULL) {
ngx_close_connection(ctx->peer.connection);
ngx_destroy_pool(ctx->pool);
ngx_imap_session_internal_server_error(s);
ngx_mail_session_internal_server_error(s);
return;
}
@ -622,21 +638,70 @@ ngx_imap_auth_http_process_headers(ngx_imap_session_t *s,
continue;
}
if (len == sizeof("Auth-Error-Code") - 1
&& ngx_strncasecmp(ctx->header_name_start,
(u_char *) "Auth-Error-Code",
sizeof("Auth-Error-Code") - 1)
== 0)
{
ctx->errcode.len = ctx->header_end - ctx->header_start;
ctx->errcode.data = ngx_palloc(s->connection->pool,
ctx->errcode.len);
if (ctx->errcode.data == NULL) {
ngx_close_connection(ctx->peer.connection);
ngx_destroy_pool(ctx->pool);
ngx_mail_session_internal_server_error(s);
return;
}
ngx_memcpy(ctx->errcode.data, ctx->header_start,
ctx->errcode.len);
continue;
}
/* ignore other headers */
continue;
}
if (rc == NGX_DONE) {
ngx_log_debug0(NGX_LOG_DEBUG_IMAP, s->connection->log, 0,
"auth http header done");
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, s->connection->log, 0,
"mail auth http header done");
ngx_close_connection(ctx->peer.connection);
if (ctx->err.len) {
ngx_log_error(NGX_LOG_INFO, s->connection->log, 0,
"client login failed: \"%V\"", &ctx->errmsg);
if (s->protocol == NGX_MAIL_SMTP_PROTOCOL) {
if (ctx->errcode.len == 0) {
ctx->errcode = ngx_mail_smtp_errcode;
}
ctx->err.len = ctx->errcode.len + ctx->errmsg.len
+ sizeof(" " CRLF) - 1;
p = ngx_palloc(s->connection->pool, ctx->err.len);
if (p == NULL) {
ngx_close_connection(ctx->peer.connection);
ngx_destroy_pool(ctx->pool);
ngx_mail_session_internal_server_error(s);
return;
}
ctx->err.data = p;
p = ngx_cpymem(p, ctx->errcode.data, ctx->errcode.len);
*p++ = ' ';
p = ngx_cpymem(p, ctx->errmsg.data, ctx->errmsg.len);
*p++ = CR; *p = LF;
}
s->out = ctx->err;
timer = ctx->sleep;
@ -644,13 +709,13 @@ ngx_imap_auth_http_process_headers(ngx_imap_session_t *s,
if (timer == 0) {
s->quit = 1;
ngx_imap_send(s->connection->write);
ngx_mail_send(s->connection->write);
return;
}
ngx_add_timer(s->connection->read, timer * 1000);
s->connection->read->handler = ngx_imap_auth_sleep_handler;
s->connection->read->handler = ngx_mail_auth_sleep_handler;
return;
}
@ -661,13 +726,13 @@ ngx_imap_auth_http_process_headers(ngx_imap_session_t *s,
ngx_destroy_pool(ctx->pool);
if (timer == 0) {
ngx_imap_auth_http_init(s);
ngx_mail_auth_http_init(s);
return;
}
ngx_add_timer(s->connection->read, timer * 1000);
s->connection->read->handler = ngx_imap_auth_sleep_handler;
s->connection->read->handler = ngx_mail_auth_sleep_handler;
return;
}
@ -677,30 +742,31 @@ ngx_imap_auth_http_process_headers(ngx_imap_session_t *s,
"auth http server %V did not send server or port",
ctx->peer.name);
ngx_destroy_pool(ctx->pool);
ngx_imap_session_internal_server_error(s);
ngx_mail_session_internal_server_error(s);
return;
}
if (s->passwd.data == NULL) {
if (s->passwd.data == NULL && s->protocol != NGX_MAIL_SMTP_PROTOCOL)
{
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
"auth http server %V did not send password",
ctx->peer.name);
ngx_destroy_pool(ctx->pool);
ngx_imap_session_internal_server_error(s);
ngx_mail_session_internal_server_error(s);
return;
}
peer = ngx_pcalloc(s->connection->pool, sizeof(ngx_peer_addr_t));
if (peer == NULL) {
ngx_destroy_pool(ctx->pool);
ngx_imap_session_internal_server_error(s);
ngx_mail_session_internal_server_error(s);
return;
}
sin = ngx_pcalloc(s->connection->pool, sizeof(struct sockaddr_in));
if (sin == NULL) {
ngx_destroy_pool(ctx->pool);
ngx_imap_session_internal_server_error(s);
ngx_mail_session_internal_server_error(s);
return;
}
@ -713,7 +779,7 @@ ngx_imap_auth_http_process_headers(ngx_imap_session_t *s,
"port:\"%V\"",
ctx->peer.name, &ctx->port);
ngx_destroy_pool(ctx->pool);
ngx_imap_session_internal_server_error(s);
ngx_mail_session_internal_server_error(s);
return;
}
@ -727,7 +793,7 @@ ngx_imap_auth_http_process_headers(ngx_imap_session_t *s,
"address:\"%V\"",
ctx->peer.name, &ctx->addr);
ngx_destroy_pool(ctx->pool);
ngx_imap_session_internal_server_error(s);
ngx_mail_session_internal_server_error(s);
return;
}
@ -741,7 +807,7 @@ ngx_imap_auth_http_process_headers(ngx_imap_session_t *s,
peer->name.data = ngx_palloc(s->connection->pool, len);
if (peer->name.data == NULL) {
ngx_destroy_pool(ctx->pool);
ngx_imap_session_internal_server_error(s);
ngx_mail_session_internal_server_error(s);
return;
}
@ -754,7 +820,7 @@ ngx_imap_auth_http_process_headers(ngx_imap_session_t *s,
ngx_memcpy(peer->name.data + len, ctx->port.data, ctx->port.len);
ngx_destroy_pool(ctx->pool);
ngx_imap_proxy_init(s, peer);
ngx_mail_proxy_init(s, peer);
return;
}
@ -770,7 +836,7 @@ ngx_imap_auth_http_process_headers(ngx_imap_session_t *s,
ctx->peer.name);
ngx_close_connection(ctx->peer.connection);
ngx_destroy_pool(ctx->pool);
ngx_imap_session_internal_server_error(s);
ngx_mail_session_internal_server_error(s);
return;
}
@ -778,13 +844,13 @@ ngx_imap_auth_http_process_headers(ngx_imap_session_t *s,
static void
ngx_imap_auth_sleep_handler(ngx_event_t *rev)
ngx_mail_auth_sleep_handler(ngx_event_t *rev)
{
ngx_connection_t *c;
ngx_imap_session_t *s;
ngx_imap_core_srv_conf_t *cscf;
ngx_mail_session_t *s;
ngx_mail_core_srv_conf_t *cscf;
ngx_log_debug0(NGX_LOG_DEBUG_IMAP, rev->log, 0, "imap auth sleep handler");
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail auth sleep handler");
c = rev->data;
s = c->data;
@ -795,30 +861,39 @@ ngx_imap_auth_sleep_handler(ngx_event_t *rev)
if (s->auth_wait) {
s->auth_wait = 0;
ngx_imap_auth_http_init(s);
ngx_mail_auth_http_init(s);
return;
}
if (s->protocol == NGX_IMAP_POP3_PROTOCOL) {
s->imap_state = ngx_pop3_start;
s->connection->read->handler = ngx_pop3_auth_state;
switch (s->protocol) {
} else {
s->imap_state = ngx_imap_start;
case NGX_MAIL_POP3_PROTOCOL:
s->mail_state = ngx_pop3_start;
s->connection->read->handler = ngx_pop3_auth_state;
break;
case NGX_MAIL_IMAP_PROTOCOL:
s->mail_state = ngx_imap_start;
s->connection->read->handler = ngx_imap_auth_state;
break;
default: /* NGX_MAIL_SMTP_PROTOCOL */
s->mail_state = ngx_smtp_start;
s->connection->read->handler = ngx_smtp_auth_state;
break;
}
s->auth_method = NGX_IMAP_AUTH_PLAIN;
s->auth_method = NGX_MAIL_AUTH_PLAIN;
c->log->action = "in auth state";
ngx_imap_send(s->connection->write);
ngx_mail_send(s->connection->write);
if (c->destroyed) {
return;
}
cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module);
cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
ngx_add_timer(rev, cscf->timeout);
@ -828,7 +903,7 @@ ngx_imap_auth_sleep_handler(ngx_event_t *rev)
}
if (ngx_handle_read_event(rev, 0) == NGX_ERROR) {
ngx_imap_close_connection(s->connection);
ngx_mail_close_connection(s->connection);
}
return;
@ -836,15 +911,15 @@ ngx_imap_auth_sleep_handler(ngx_event_t *rev)
if (rev->active) {
if (ngx_handle_read_event(rev, 0) == NGX_ERROR) {
ngx_imap_close_connection(s->connection);
ngx_mail_close_connection(s->connection);
}
}
}
static ngx_int_t
ngx_imap_auth_http_parse_header_line(ngx_imap_session_t *s,
ngx_imap_auth_http_ctx_t *ctx)
ngx_mail_auth_http_parse_header_line(ngx_mail_session_t *s,
ngx_mail_auth_http_ctx_t *ctx)
{
u_char c, ch, *p;
ngx_uint_t hash;
@ -1035,56 +1110,56 @@ header_done:
static void
ngx_imap_auth_http_block_read(ngx_event_t *rev)
ngx_mail_auth_http_block_read(ngx_event_t *rev)
{
ngx_connection_t *c;
ngx_imap_session_t *s;
ngx_imap_auth_http_ctx_t *ctx;
ngx_mail_session_t *s;
ngx_mail_auth_http_ctx_t *ctx;
ngx_log_debug0(NGX_LOG_DEBUG_IMAP, rev->log, 0,
"imap auth http block read");
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0,
"mail auth http block read");
if (ngx_handle_read_event(rev, 0) == NGX_ERROR) {
c = rev->data;
s = c->data;
ctx = ngx_imap_get_module_ctx(s, ngx_imap_auth_http_module);
ctx = ngx_mail_get_module_ctx(s, ngx_mail_auth_http_module);
ngx_close_connection(ctx->peer.connection);
ngx_destroy_pool(ctx->pool);
ngx_imap_session_internal_server_error(s);
ngx_mail_session_internal_server_error(s);
}
}
static void
ngx_imap_auth_http_dummy_handler(ngx_event_t *ev)
ngx_mail_auth_http_dummy_handler(ngx_event_t *ev)
{
ngx_log_debug0(NGX_LOG_DEBUG_IMAP, ev->log, 0,
"imap auth http dummy handler");
ngx_log_debug0(NGX_LOG_DEBUG_MAIL, ev->log, 0,
"mail auth http dummy handler");
}
static ngx_buf_t *
ngx_imap_auth_http_create_request(ngx_imap_session_t *s, ngx_pool_t *pool,
ngx_imap_auth_http_conf_t *ahcf)
ngx_mail_auth_http_create_request(ngx_mail_session_t *s, ngx_pool_t *pool,
ngx_mail_auth_http_conf_t *ahcf)
{
size_t len;
ngx_buf_t *b;
ngx_str_t login, passwd;
if (ngx_imap_auth_http_escape(pool, &s->login, &login) != NGX_OK) {
if (ngx_mail_auth_http_escape(pool, &s->login, &login) != NGX_OK) {
return NULL;
}
if (ngx_imap_auth_http_escape(pool, &s->passwd, &passwd) != NGX_OK) {
if (ngx_mail_auth_http_escape(pool, &s->passwd, &passwd) != NGX_OK) {
return NULL;
}
len = sizeof("GET ") - 1 + ahcf->uri.len + sizeof(" HTTP/1.0" CRLF) - 1
+ sizeof("Host: ") - 1 + ahcf->host_header.len + sizeof(CRLF) - 1
+ sizeof("Auth-Method: ") - 1
+ ngx_imap_auth_http_method[s->auth_method].len
+ ngx_mail_auth_http_method[s->auth_method].len
+ sizeof(CRLF) - 1
+ sizeof("Auth-User: ") - 1 + login.len + sizeof(CRLF) - 1
+ sizeof("Auth-Pass: ") - 1 + passwd.len + sizeof(CRLF) - 1
@ -1114,8 +1189,8 @@ ngx_imap_auth_http_create_request(ngx_imap_session_t *s, ngx_pool_t *pool,
b->last = ngx_cpymem(b->last, "Auth-Method: ",
sizeof("Auth-Method: ") - 1);
b->last = ngx_cpymem(b->last,
ngx_imap_auth_http_method[s->auth_method].data,
ngx_imap_auth_http_method[s->auth_method].len);
ngx_mail_auth_http_method[s->auth_method].data,
ngx_mail_auth_http_method[s->auth_method].len);
*b->last++ = CR; *b->last++ = LF;
b->last = ngx_cpymem(b->last, "Auth-User: ", sizeof("Auth-User: ") - 1);
@ -1126,7 +1201,7 @@ ngx_imap_auth_http_create_request(ngx_imap_session_t *s, ngx_pool_t *pool,
b->last = ngx_copy(b->last, passwd.data, passwd.len);
*b->last++ = CR; *b->last++ = LF;
if (s->auth_method != NGX_IMAP_AUTH_PLAIN && s->salt.len) {
if (s->auth_method != NGX_MAIL_AUTH_PLAIN && s->salt.len) {
b->last = ngx_cpymem(b->last, "Auth-Salt: ", sizeof("Auth-Salt: ") - 1);
b->last = ngx_copy(b->last, s->salt.data, s->salt.len);
@ -1135,7 +1210,7 @@ ngx_imap_auth_http_create_request(ngx_imap_session_t *s, ngx_pool_t *pool,
b->last = ngx_cpymem(b->last, "Auth-Protocol: ",
sizeof("Auth-Protocol: ") - 1);
b->last = ngx_cpymem(b->last, ngx_imap_auth_http_protocol[s->protocol],
b->last = ngx_cpymem(b->last, ngx_mail_auth_http_protocol[s->protocol],
sizeof("imap") - 1);
*b->last++ = CR; *b->last++ = LF;
@ -1154,14 +1229,14 @@ ngx_imap_auth_http_create_request(ngx_imap_session_t *s, ngx_pool_t *pool,
/* add "\r\n" at the header end */
*b->last++ = CR; *b->last++ = LF;
#if (NGX_DEBUG_IMAP_PASSWD)
#if (NGX_DEBUG_MAIL_PASSWD)
{
ngx_str_t l;
l.len = b->last - b->pos;
l.data = b->pos;
ngx_log_debug1(NGX_LOG_DEBUG_IMAP, s->connection->log, 0,
"imap auth http header:\n\"%V\"", &l);
ngx_log_debug1(NGX_LOG_DEBUG_MAIL, s->connection->log, 0,
"mail auth http header:\n\"%V\"", &l);
}
#endif
@ -1170,7 +1245,7 @@ ngx_imap_auth_http_create_request(ngx_imap_session_t *s, ngx_pool_t *pool,
static ngx_int_t
ngx_imap_auth_http_escape(ngx_pool_t *pool, ngx_str_t *text, ngx_str_t *escaped)
ngx_mail_auth_http_escape(ngx_pool_t *pool, ngx_str_t *text, ngx_str_t *escaped)
{
u_char ch, *p;
ngx_uint_t i, n;
@ -1224,11 +1299,11 @@ ngx_imap_auth_http_escape(ngx_pool_t *pool, ngx_str_t *text, ngx_str_t *escaped)
static void *
ngx_imap_auth_http_create_conf(ngx_conf_t *cf)
ngx_mail_auth_http_create_conf(ngx_conf_t *cf)
{
ngx_imap_auth_http_conf_t *ahcf;
ngx_mail_auth_http_conf_t *ahcf;
ahcf = ngx_pcalloc(cf->pool, sizeof(ngx_imap_auth_http_conf_t));
ahcf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_auth_http_conf_t));
if (ahcf == NULL) {
return NGX_CONF_ERROR;
}
@ -1240,10 +1315,10 @@ ngx_imap_auth_http_create_conf(ngx_conf_t *cf)
static char *
ngx_imap_auth_http_merge_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_mail_auth_http_merge_conf(ngx_conf_t *cf, void *parent, void *child)
{
ngx_imap_auth_http_conf_t *prev = parent;
ngx_imap_auth_http_conf_t *conf = child;
ngx_mail_auth_http_conf_t *prev = parent;
ngx_mail_auth_http_conf_t *conf = child;
u_char *p;
size_t len;
@ -1291,9 +1366,9 @@ ngx_imap_auth_http_merge_conf(ngx_conf_t *cf, void *parent, void *child)
static char *
ngx_imap_auth_http(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_mail_auth_http(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_imap_auth_http_conf_t *ahcf = conf;
ngx_mail_auth_http_conf_t *ahcf = conf;
ngx_str_t *value;
ngx_url_t u;
@ -1329,9 +1404,9 @@ ngx_imap_auth_http(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
static char *
ngx_imap_auth_http_header(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_mail_auth_http_header(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_imap_auth_http_conf_t *ahcf = conf;
ngx_mail_auth_http_conf_t *ahcf = conf;
ngx_str_t *value;
ngx_table_elt_t *header;

View File

@ -7,24 +7,25 @@
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_event.h>
#include <ngx_imap.h>
#include <ngx_mail.h>
static void *ngx_imap_core_create_main_conf(ngx_conf_t *cf);
static void *ngx_imap_core_create_srv_conf(ngx_conf_t *cf);
static char *ngx_imap_core_merge_srv_conf(ngx_conf_t *cf, void *parent,
static void *ngx_mail_core_create_main_conf(ngx_conf_t *cf);
static void *ngx_mail_core_create_srv_conf(ngx_conf_t *cf);
static char *ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent,
void *child);
static char *ngx_imap_core_server(ngx_conf_t *cf, ngx_command_t *cmd,
static char *ngx_mail_core_server(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_imap_core_listen(ngx_conf_t *cf, ngx_command_t *cmd,
static char *ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_imap_core_capability(ngx_conf_t *cf, ngx_command_t *cmd,
static char *ngx_mail_core_capability(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static ngx_conf_enum_t ngx_imap_core_procotol[] = {
{ ngx_string("pop3"), NGX_IMAP_POP3_PROTOCOL },
{ ngx_string("imap"), NGX_IMAP_IMAP_PROTOCOL },
static ngx_conf_enum_t ngx_mail_core_procotol[] = {
{ ngx_string("pop3"), NGX_MAIL_POP3_PROTOCOL },
{ ngx_string("imap"), NGX_MAIL_IMAP_PROTOCOL },
{ ngx_string("smtp"), NGX_MAIL_SMTP_PROTOCOL },
{ ngx_null_string, 0 }
};
@ -45,14 +46,30 @@ static ngx_str_t ngx_imap_default_capabilities[] = {
};
static ngx_conf_bitmask_t ngx_imap_auth_methods[] = {
{ ngx_string("plain"), NGX_IMAP_AUTH_PLAIN_ENABLED },
{ ngx_string("apop"), NGX_IMAP_AUTH_APOP_ENABLED },
{ ngx_string("cram-md5"), NGX_IMAP_AUTH_CRAM_MD5_ENABLED },
static ngx_conf_bitmask_t ngx_pop3_auth_methods[] = {
{ ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED },
{ ngx_string("apop"), NGX_MAIL_AUTH_APOP_ENABLED },
{ ngx_string("cram-md5"), NGX_MAIL_AUTH_CRAM_MD5_ENABLED },
{ ngx_null_string, 0 }
};
static ngx_conf_bitmask_t ngx_smtp_auth_methods[] = {
{ ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED },
{ ngx_string("login"), NGX_MAIL_AUTH_LOGIN_ENABLED },
{ ngx_string("cram-md5"), NGX_MAIL_AUTH_CRAM_MD5_ENABLED },
{ ngx_null_string, 0 }
};
static ngx_str_t ngx_smtp_auth_methods_names[] = {
ngx_string("PLAIN"),
ngx_string("LOGIN"),
ngx_null_string, /* APOP */
ngx_string("CRAM-MD5")
};
static ngx_str_t ngx_pop3_auth_plain_capability =
ngx_string("+OK methods supported:" CRLF
"LOGIN" CRLF
@ -69,96 +86,117 @@ static ngx_str_t ngx_pop3_auth_cram_md5_capability =
static ngx_command_t ngx_imap_core_commands[] = {
static ngx_command_t ngx_mail_core_commands[] = {
{ ngx_string("server"),
NGX_IMAP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
ngx_imap_core_server,
NGX_MAIL_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
ngx_mail_core_server,
0,
0,
NULL },
{ ngx_string("listen"),
NGX_IMAP_SRV_CONF|NGX_CONF_TAKE12,
ngx_imap_core_listen,
NGX_MAIL_SRV_CONF|NGX_CONF_TAKE12,
ngx_mail_core_listen,
0,
0,
NULL },
{ ngx_string("protocol"),
NGX_IMAP_SRV_CONF|NGX_CONF_TAKE1,
NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
ngx_conf_set_enum_slot,
NGX_IMAP_SRV_CONF_OFFSET,
offsetof(ngx_imap_core_srv_conf_t, protocol),
&ngx_imap_core_procotol },
NGX_MAIL_SRV_CONF_OFFSET,
offsetof(ngx_mail_core_srv_conf_t, protocol),
&ngx_mail_core_procotol },
{ ngx_string("imap_client_buffer"),
NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_TAKE1,
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
ngx_conf_set_size_slot,
NGX_IMAP_SRV_CONF_OFFSET,
offsetof(ngx_imap_core_srv_conf_t, imap_client_buffer_size),
NGX_MAIL_SRV_CONF_OFFSET,
offsetof(ngx_mail_core_srv_conf_t, imap_client_buffer_size),
NULL },
{ ngx_string("so_keepalive"),
NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_FLAG,
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
NGX_IMAP_SRV_CONF_OFFSET,
offsetof(ngx_imap_core_srv_conf_t, so_keepalive),
NGX_MAIL_SRV_CONF_OFFSET,
offsetof(ngx_mail_core_srv_conf_t, so_keepalive),
NULL },
{ ngx_string("timeout"),
NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_TAKE1,
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
ngx_conf_set_msec_slot,
NGX_IMAP_SRV_CONF_OFFSET,
offsetof(ngx_imap_core_srv_conf_t, timeout),
NGX_MAIL_SRV_CONF_OFFSET,
offsetof(ngx_mail_core_srv_conf_t, timeout),
NULL },
{ ngx_string("pop3_capabilities"),
NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_1MORE,
ngx_imap_core_capability,
NGX_IMAP_SRV_CONF_OFFSET,
offsetof(ngx_imap_core_srv_conf_t, pop3_capabilities),
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
ngx_mail_core_capability,
NGX_MAIL_SRV_CONF_OFFSET,
offsetof(ngx_mail_core_srv_conf_t, pop3_capabilities),
NULL },
{ ngx_string("imap_capabilities"),
NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_1MORE,
ngx_imap_core_capability,
NGX_IMAP_SRV_CONF_OFFSET,
offsetof(ngx_imap_core_srv_conf_t, imap_capabilities),
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
ngx_mail_core_capability,
NGX_MAIL_SRV_CONF_OFFSET,
offsetof(ngx_mail_core_srv_conf_t, imap_capabilities),
NULL },
{ ngx_string("smtp_capabilities"),
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
ngx_mail_core_capability,
NGX_MAIL_SRV_CONF_OFFSET,
offsetof(ngx_mail_core_srv_conf_t, smtp_capabilities),
NULL },
{ ngx_string("server_name"),
NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_TAKE1,
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
NGX_IMAP_SRV_CONF_OFFSET,
offsetof(ngx_imap_core_srv_conf_t, server_name),
NGX_MAIL_SRV_CONF_OFFSET,
offsetof(ngx_mail_core_srv_conf_t, server_name),
NULL },
{ ngx_string("auth"),
NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_1MORE,
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
ngx_conf_set_bitmask_slot,
NGX_IMAP_SRV_CONF_OFFSET,
offsetof(ngx_imap_core_srv_conf_t, auth_methods),
&ngx_imap_auth_methods },
NGX_MAIL_SRV_CONF_OFFSET,
offsetof(ngx_mail_core_srv_conf_t, pop3_auth_methods),
&ngx_pop3_auth_methods },
{ ngx_string("pop3_auth"),
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
ngx_conf_set_bitmask_slot,
NGX_MAIL_SRV_CONF_OFFSET,
offsetof(ngx_mail_core_srv_conf_t, pop3_auth_methods),
&ngx_pop3_auth_methods },
{ ngx_string("smtp_auth"),
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
ngx_conf_set_bitmask_slot,
NGX_MAIL_SRV_CONF_OFFSET,
offsetof(ngx_mail_core_srv_conf_t, smtp_auth_methods),
&ngx_smtp_auth_methods },
ngx_null_command
};
static ngx_imap_module_t ngx_imap_core_module_ctx = {
ngx_imap_core_create_main_conf, /* create main configuration */
static ngx_mail_module_t ngx_mail_core_module_ctx = {
ngx_mail_core_create_main_conf, /* create main configuration */
NULL, /* init main configuration */
ngx_imap_core_create_srv_conf, /* create server configuration */
ngx_imap_core_merge_srv_conf /* merge server configuration */
ngx_mail_core_create_srv_conf, /* create server configuration */
ngx_mail_core_merge_srv_conf /* merge server configuration */
};
ngx_module_t ngx_imap_core_module = {
ngx_module_t ngx_mail_core_module = {
NGX_MODULE_V1,
&ngx_imap_core_module_ctx, /* module context */
ngx_imap_core_commands, /* module directives */
NGX_IMAP_MODULE, /* module type */
&ngx_mail_core_module_ctx, /* module context */
ngx_mail_core_commands, /* module directives */
NGX_MAIL_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
NULL, /* init process */
@ -171,23 +209,23 @@ ngx_module_t ngx_imap_core_module = {
static void *
ngx_imap_core_create_main_conf(ngx_conf_t *cf)
ngx_mail_core_create_main_conf(ngx_conf_t *cf)
{
ngx_imap_core_main_conf_t *cmcf;
ngx_mail_core_main_conf_t *cmcf;
cmcf = ngx_pcalloc(cf->pool, sizeof(ngx_imap_core_main_conf_t));
cmcf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_core_main_conf_t));
if (cmcf == NULL) {
return NGX_CONF_ERROR;
}
if (ngx_array_init(&cmcf->servers, cf->pool, 4,
sizeof(ngx_imap_core_srv_conf_t *))
sizeof(ngx_mail_core_srv_conf_t *))
!= NGX_OK)
{
return NGX_CONF_ERROR;
}
if (ngx_array_init(&cmcf->listen, cf->pool, 4, sizeof(ngx_imap_listen_t))
if (ngx_array_init(&cmcf->listen, cf->pool, 4, sizeof(ngx_mail_listen_t))
!= NGX_OK)
{
return NGX_CONF_ERROR;
@ -198,11 +236,11 @@ ngx_imap_core_create_main_conf(ngx_conf_t *cf)
static void *
ngx_imap_core_create_srv_conf(ngx_conf_t *cf)
ngx_mail_core_create_srv_conf(ngx_conf_t *cf)
{
ngx_imap_core_srv_conf_t *cscf;
ngx_mail_core_srv_conf_t *cscf;
cscf = ngx_pcalloc(cf->pool, sizeof(ngx_imap_core_srv_conf_t));
cscf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_core_srv_conf_t));
if (cscf == NULL) {
return NULL;
}
@ -224,32 +262,46 @@ ngx_imap_core_create_srv_conf(ngx_conf_t *cf)
return NULL;
}
if (ngx_array_init(&cscf->smtp_capabilities, cf->pool, 4, sizeof(ngx_str_t))
!= NGX_OK)
{
return NULL;
}
return cscf;
}
static char *
ngx_imap_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
{
ngx_imap_core_srv_conf_t *prev = parent;
ngx_imap_core_srv_conf_t *conf = child;
ngx_mail_core_srv_conf_t *prev = parent;
ngx_mail_core_srv_conf_t *conf = child;
u_char *p;
size_t size;
size_t size, stls_only_size;
ngx_str_t *c, *d;
ngx_uint_t i;
ngx_uint_t i, m;
ngx_conf_merge_size_value(conf->imap_client_buffer_size,
prev->imap_client_buffer_size,
(size_t) ngx_pagesize);
ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 60000);
ngx_conf_merge_uint_value(conf->protocol, prev->protocol,
NGX_IMAP_IMAP_PROTOCOL);
NGX_MAIL_IMAP_PROTOCOL);
ngx_conf_merge_value(conf->so_keepalive, prev->so_keepalive, 0);
ngx_conf_merge_bitmask_value(conf->auth_methods, prev->auth_methods,
(NGX_CONF_BITMASK_SET|NGX_IMAP_AUTH_PLAIN_ENABLED));
ngx_conf_merge_bitmask_value(conf->pop3_auth_methods,
prev->pop3_auth_methods,
(NGX_CONF_BITMASK_SET
|NGX_MAIL_AUTH_PLAIN_ENABLED));
ngx_conf_merge_bitmask_value(conf->smtp_auth_methods,
prev->smtp_auth_methods,
(NGX_CONF_BITMASK_SET
|NGX_MAIL_AUTH_PLAIN_ENABLED
|NGX_MAIL_AUTH_LOGIN_ENABLED));
ngx_conf_merge_str_value(conf->server_name, prev->server_name, "");
@ -291,12 +343,20 @@ ngx_imap_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
size = sizeof("+OK Capability list follows" CRLF) - 1
+ sizeof("." CRLF) - 1;
stls_only_size = size + sizeof("STLS" CRLF) - 1;
c = conf->pop3_capabilities.elts;
for (i = 0; i < conf->pop3_capabilities.nelts; i++) {
size += c[i].len + sizeof(CRLF) - 1;
if (ngx_strcasecmp(c[i].data, (u_char *) "USER") == 0) {
continue;
}
stls_only_size += c[i].len + sizeof(CRLF) - 1;
}
if (conf->auth_methods & NGX_IMAP_AUTH_CRAM_MD5_ENABLED) {
if (conf->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) {
size += sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1;
} else {
@ -319,7 +379,7 @@ ngx_imap_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
*p++ = CR; *p++ = LF;
}
if (conf->auth_methods & NGX_IMAP_AUTH_CRAM_MD5_ENABLED) {
if (conf->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) {
p = ngx_cpymem(p, "SASL LOGIN PLAIN CRAM-MD5" CRLF,
sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1);
@ -348,7 +408,7 @@ ngx_imap_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
*p++ = '.'; *p++ = CR; *p = LF;
if (conf->auth_methods & NGX_IMAP_AUTH_CRAM_MD5_ENABLED) {
if (conf->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) {
conf->pop3_auth_capability = ngx_pop3_auth_cram_md5_capability;
} else {
@ -356,6 +416,30 @@ ngx_imap_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
}
p = ngx_palloc(cf->pool, stls_only_size);
if (p == NULL) {
return NGX_CONF_ERROR;
}
conf->pop3_starttls_only_capability.len = stls_only_size;
conf->pop3_starttls_only_capability.data = p;
p = ngx_cpymem(p, "+OK Capability list follows" CRLF,
sizeof("+OK Capability list follows" CRLF) - 1);
for (i = 0; i < conf->pop3_capabilities.nelts; i++) {
if (ngx_strcasecmp(c[i].data, (u_char *) "USER") == 0) {
continue;
}
p = ngx_cpymem(p, c[i].data, c[i].len);
*p++ = CR; *p++ = LF;
}
p = ngx_cpymem(p, "STLS" CRLF, sizeof("STLS" CRLF) - 1);
*p++ = '.'; *p++ = CR; *p = LF;
if (conf->imap_capabilities.nelts == 0) {
conf->imap_capabilities = prev->imap_capabilities;
}
@ -372,7 +456,7 @@ ngx_imap_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
}
}
size = sizeof("* CAPABILITY") - 1 + sizeof(CRLF) - 1;
size = sizeof("* CAPABILITY" CRLF) - 1;
c = conf->imap_capabilities.elts;
for (i = 0; i < conf->imap_capabilities.nelts; i++) {
@ -429,40 +513,125 @@ ngx_imap_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
*p++ = CR; *p = LF;
size = sizeof("220 ESMTP ready" CRLF) - 1 + conf->server_name.len;
p = ngx_palloc(cf->pool, size);
if (p == NULL) {
return NGX_CONF_ERROR;
}
conf->smtp_greeting.len = size;
conf->smtp_greeting.data = p;
*p++ = '2'; *p++ = '2'; *p++ = '0'; *p++ = ' ';
p = ngx_cpymem(p, conf->server_name.data, conf->server_name.len);
ngx_memcpy(p, " ESMTP ready" CRLF, sizeof(" ESMTP ready" CRLF) - 1);
size = sizeof("250 " CRLF) - 1 + conf->server_name.len;
p = ngx_palloc(cf->pool, size);
if (p == NULL) {
return NGX_CONF_ERROR;
}
conf->smtp_server_name.len = size;
conf->smtp_server_name.data = p;
*p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = ' ';
p = ngx_cpymem(p, conf->server_name.data, conf->server_name.len);
*p++ = CR; *p = LF;
if (conf->smtp_capabilities.nelts == 0) {
conf->smtp_capabilities = prev->smtp_capabilities;
}
size = sizeof("250-") - 1 + conf->server_name.len + sizeof(CRLF) - 1
+ sizeof("250 AUTH") - 1 + sizeof(CRLF) - 1;
c = conf->smtp_capabilities.elts;
for (i = 0; i < conf->smtp_capabilities.nelts; i++) {
size += sizeof("250 ") - 1 + c[i].len + sizeof(CRLF) - 1;
}
for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED;
m <<= 1, i++)
{
if (m & conf->smtp_auth_methods) {
size += 1 + ngx_smtp_auth_methods_names[i].len;
}
}
p = ngx_palloc(cf->pool, size);
if (p == NULL) {
return NGX_CONF_ERROR;
}
conf->smtp_capability.len = size;
conf->smtp_capability.data = p;
*p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = '-';
p = ngx_cpymem(p, conf->server_name.data, conf->server_name.len);
*p++ = CR; *p++ = LF;
for (i = 0; i < conf->smtp_capabilities.nelts; i++) {
*p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = '-';
p = ngx_cpymem(p, c[i].data, c[i].len);
*p++ = CR; *p++ = LF;
}
*p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = ' ';
*p++ = 'A'; *p++ = 'U'; *p++ = 'T'; *p++ = 'H';
for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0;
m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED;
m <<= 1, i++)
{
if (m & conf->smtp_auth_methods) {
*p++ = ' ';
p = ngx_cpymem(p, ngx_smtp_auth_methods_names[i].data,
ngx_smtp_auth_methods_names[i].len);
}
}
*p++ = CR; *p = LF;
return NGX_CONF_OK;
}
static char *
ngx_imap_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_mail_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
char *rv;
void *mconf;
ngx_uint_t m;
ngx_conf_t pcf;
ngx_imap_module_t *module;
ngx_imap_conf_ctx_t *ctx, *imap_ctx;
ngx_imap_core_srv_conf_t *cscf, **cscfp;
ngx_imap_core_main_conf_t *cmcf;
ngx_mail_module_t *module;
ngx_mail_conf_ctx_t *ctx, *mail_ctx;
ngx_mail_core_srv_conf_t *cscf, **cscfp;
ngx_mail_core_main_conf_t *cmcf;
ctx = ngx_pcalloc(cf->pool, sizeof(ngx_imap_conf_ctx_t));
ctx = ngx_pcalloc(cf->pool, sizeof(ngx_mail_conf_ctx_t));
if (ctx == NULL) {
return NGX_CONF_ERROR;
}
imap_ctx = cf->ctx;
ctx->main_conf = imap_ctx->main_conf;
mail_ctx = cf->ctx;
ctx->main_conf = mail_ctx->main_conf;
/* the server{}'s srv_conf */
ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_imap_max_module);
ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_mail_max_module);
if (ctx->srv_conf == NULL) {
return NGX_CONF_ERROR;
}
for (m = 0; ngx_modules[m]; m++) {
if (ngx_modules[m]->type != NGX_IMAP_MODULE) {
if (ngx_modules[m]->type != NGX_MAIL_MODULE) {
continue;
}
@ -480,10 +649,10 @@ ngx_imap_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
/* the server configuration context */
cscf = ctx->srv_conf[ngx_imap_core_module.ctx_index];
cscf = ctx->srv_conf[ngx_mail_core_module.ctx_index];
cscf->ctx = ctx;
cmcf = ctx->main_conf[ngx_imap_core_module.ctx_index];
cmcf = ctx->main_conf[ngx_mail_core_module.ctx_index];
cscfp = ngx_array_push(&cmcf->servers);
if (cscfp == NULL) {
@ -497,7 +666,7 @@ ngx_imap_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
pcf = *cf;
cf->ctx = ctx;
cf->cmd_type = NGX_IMAP_SRV_CONF;
cf->cmd_type = NGX_MAIL_SRV_CONF;
rv = ngx_conf_parse(cf, NULL);
@ -510,13 +679,13 @@ ngx_imap_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
/* AF_INET only */
static char *
ngx_imap_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_str_t *value;
ngx_url_t u;
ngx_uint_t i;
ngx_imap_listen_t *imls;
ngx_imap_core_main_conf_t *cmcf;
ngx_mail_listen_t *imls;
ngx_mail_core_main_conf_t *cmcf;
value = cf->args->elts;
@ -535,7 +704,7 @@ ngx_imap_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
cmcf = ngx_imap_conf_get_module_main_conf(cf, ngx_imap_core_module);
cmcf = ngx_mail_conf_get_module_main_conf(cf, ngx_mail_core_module);
imls = cmcf->listen.elts;
@ -555,7 +724,7 @@ ngx_imap_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
ngx_memzero(imls, sizeof(ngx_imap_listen_t));
ngx_memzero(imls, sizeof(ngx_mail_listen_t));
imls->addr = u.addr.in_addr;
imls->port = u.port;
@ -578,7 +747,7 @@ ngx_imap_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
static char *
ngx_imap_core_capability(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_mail_core_capability(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
char *p = conf;

1838
src/mail/ngx_mail_handler.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -7,10 +7,207 @@
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_event.h>
#include <ngx_imap.h>
#include <ngx_mail.h>
ngx_int_t ngx_imap_parse_command(ngx_imap_session_t *s)
ngx_int_t ngx_pop3_parse_command(ngx_mail_session_t *s)
{
u_char ch, *p, *c, c0, c1, c2, c3;
ngx_str_t *arg;
enum {
sw_start = 0,
sw_spaces_before_argument,
sw_argument,
sw_almost_done
} state;
state = s->state;
for (p = s->buffer->pos; p < s->buffer->last; p++) {
ch = *p;
switch (state) {
/* POP3 command */
case sw_start:
if (ch == ' ' || ch == CR || ch == LF) {
c = s->buffer->start;
if (p - c == 4) {
c0 = ngx_toupper(c[0]);
c1 = ngx_toupper(c[1]);
c2 = ngx_toupper(c[2]);
c3 = ngx_toupper(c[3]);
if (c0 == 'U' && c1 == 'S' && c2 == 'E' && c3 == 'R')
{
s->command = NGX_POP3_USER;
} else if (c0 == 'P' && c1 == 'A' && c2 == 'S' && c3 == 'S')
{
s->command = NGX_POP3_PASS;
} else if (c0 == 'A' && c1 == 'P' && c2 == 'O' && c3 == 'P')
{
s->command = NGX_POP3_APOP;
} else if (c0 == 'Q' && c1 == 'U' && c2 == 'I' && c3 == 'T')
{
s->command = NGX_POP3_QUIT;
} else if (c0 == 'C' && c1 == 'A' && c2 == 'P' && c3 == 'A')
{
s->command = NGX_POP3_CAPA;
} else if (c0 == 'A' && c1 == 'U' && c2 == 'T' && c3 == 'H')
{
s->command = NGX_POP3_AUTH;
} else if (c0 == 'N' && c1 == 'O' && c2 == 'O' && c3 == 'P')
{
s->command = NGX_POP3_NOOP;
#if (NGX_MAIL_SSL)
} else if (c0 == 'S' && c1 == 'T' && c2 == 'L' && c3 == 'S')
{
s->command = NGX_POP3_STLS;
#endif
} else {
goto invalid;
}
} else {
goto invalid;
}
switch (ch) {
case ' ':
state = sw_spaces_before_argument;
break;
case CR:
state = sw_almost_done;
break;
case LF:
goto done;
}
break;
}
if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z')) {
goto invalid;
}
break;
case sw_spaces_before_argument:
switch (ch) {
case ' ':
break;
case CR:
state = sw_almost_done;
s->arg_end = p;
break;
case LF:
s->arg_end = p;
goto done;
default:
if (s->args.nelts <= 2) {
state = sw_argument;
s->arg_start = p;
break;
}
goto invalid;
}
break;
case sw_argument:
switch (ch) {
case ' ':
/*
* the space should be considered as part of the at username
* or password, but not of argument in other commands
*/
if (s->command == NGX_POP3_USER
|| s->command == NGX_POP3_PASS)
{
break;
}
/* fall through */
case CR:
case LF:
arg = ngx_array_push(&s->args);
if (arg == NULL) {
return NGX_ERROR;
}
arg->len = p - s->arg_start;
arg->data = s->arg_start;
s->arg_start = NULL;
switch (ch) {
case ' ':
state = sw_spaces_before_argument;
break;
case CR:
state = sw_almost_done;
break;
case LF:
goto done;
}
break;
default:
break;
}
break;
case sw_almost_done:
switch (ch) {
case LF:
goto done;
default:
goto invalid;
}
}
}
s->buffer->pos = p;
s->state = state;
return NGX_AGAIN;
done:
s->buffer->pos = p + 1;
if (s->arg_start) {
arg = ngx_array_push(&s->args);
if (arg == NULL) {
return NGX_ERROR;
}
arg->len = s->arg_end - s->arg_start;
arg->data = s->arg_start;
s->arg_start = NULL;
}
s->state = (s->command != NGX_POP3_AUTH) ? sw_start : sw_argument;
return NGX_OK;
invalid:
s->state = sw_start;
s->arg_start = NULL;
return NGX_MAIL_PARSE_INVALID_COMMAND;
}
ngx_int_t ngx_imap_parse_command(ngx_mail_session_t *s)
{
u_char ch, *p, *c;
ngx_str_t *arg;
@ -46,10 +243,10 @@ ngx_int_t ngx_imap_parse_command(ngx_imap_session_t *s)
break;
case CR:
s->state = sw_start;
return NGX_IMAP_PARSE_INVALID_COMMAND;
return NGX_MAIL_PARSE_INVALID_COMMAND;
case LF:
s->state = sw_start;
return NGX_IMAP_PARSE_INVALID_COMMAND;
return NGX_MAIL_PARSE_INVALID_COMMAND;
}
break;
@ -59,10 +256,10 @@ ngx_int_t ngx_imap_parse_command(ngx_imap_session_t *s)
break;
case CR:
s->state = sw_start;
return NGX_IMAP_PARSE_INVALID_COMMAND;
return NGX_MAIL_PARSE_INVALID_COMMAND;
case LF:
s->state = sw_start;
return NGX_IMAP_PARSE_INVALID_COMMAND;
return NGX_MAIL_PARSE_INVALID_COMMAND;
default:
s->cmd_start = p;
state = sw_command;
@ -119,7 +316,7 @@ ngx_int_t ngx_imap_parse_command(ngx_imap_session_t *s)
}
break;
#if (NGX_IMAP_SSL)
#if (NGX_MAIL_SSL)
case 8:
if ((c[0] == 'S'|| c[0] == 's')
&& (c[1] == 'T'|| c[1] == 't')
@ -387,11 +584,11 @@ invalid:
s->no_sync_literal = 0;
s->literal_len = 0;
return NGX_IMAP_PARSE_INVALID_COMMAND;
return NGX_MAIL_PARSE_INVALID_COMMAND;
}
ngx_int_t ngx_pop3_parse_command(ngx_imap_session_t *s)
ngx_int_t ngx_smtp_parse_command(ngx_mail_session_t *s)
{
u_char ch, *p, *c, c0, c1, c2, c3;
ngx_str_t *arg;
@ -409,7 +606,7 @@ ngx_int_t ngx_pop3_parse_command(ngx_imap_session_t *s)
switch (state) {
/* POP3 command */
/* SMTP command */
case sw_start:
if (ch == ' ' || ch == CR || ch == LF) {
c = s->buffer->start;
@ -421,38 +618,34 @@ ngx_int_t ngx_pop3_parse_command(ngx_imap_session_t *s)
c2 = ngx_toupper(c[2]);
c3 = ngx_toupper(c[3]);
if (c0 == 'U' && c1 == 'S' && c2 == 'E' && c3 == 'R')
if (c0 == 'H' && c1 == 'E' && c2 == 'L' && c3 == 'O')
{
s->command = NGX_POP3_USER;
s->command = NGX_SMTP_HELO;
} else if (c0 == 'P' && c1 == 'A' && c2 == 'S' && c3 == 'S')
} else if (c0 == 'E' && c1 == 'H' && c2 == 'L' && c3 == 'O')
{
s->command = NGX_POP3_PASS;
} else if (c0 == 'A' && c1 == 'P' && c2 == 'O' && c3 == 'P')
{
s->command = NGX_POP3_APOP;
s->command = NGX_SMTP_EHLO;
} else if (c0 == 'Q' && c1 == 'U' && c2 == 'I' && c3 == 'T')
{
s->command = NGX_POP3_QUIT;
} else if (c0 == 'C' && c1 == 'A' && c2 == 'P' && c3 == 'A')
{
s->command = NGX_POP3_CAPA;
s->command = NGX_SMTP_QUIT;
} else if (c0 == 'A' && c1 == 'U' && c2 == 'T' && c3 == 'H')
{
s->command = NGX_POP3_AUTH;
s->command = NGX_SMTP_AUTH;
} else if (c0 == 'N' && c1 == 'O' && c2 == 'O' && c3 == 'P')
{
s->command = NGX_POP3_NOOP;
#if (NGX_IMAP_SSL)
} else if (c0 == 'S' && c1 == 'T' && c2 == 'L' && c3 == 'S')
s->command = NGX_SMTP_NOOP;
} else if (c0 == 'M' && c1 == 'A' && c2 == 'I' && c3 == 'L')
{
s->command = NGX_POP3_STLS;
#endif
s->command = NGX_SMTP_MAIL;
} else if (c0 == 'R' && c1 == 'S' && c2 == 'E' && c3 == 'T')
{
s->command = NGX_SMTP_RSET;
} else {
goto invalid;
}
@ -503,22 +696,7 @@ ngx_int_t ngx_pop3_parse_command(ngx_imap_session_t *s)
case sw_argument:
switch (ch) {
case ' ':
/*
* the space should be considered as part of the at username
* or password, but not of argument in other commands
*/
if (s->command == NGX_POP3_USER
|| s->command == NGX_POP3_PASS)
{
break;
}
/* fall through */
case CR:
case LF:
arg = ngx_array_push(&s->args);
@ -575,7 +753,8 @@ done:
s->arg_start = NULL;
}
s->state = (s->command != NGX_POP3_AUTH) ? sw_start : sw_argument;
s->state = (s->command != NGX_SMTP_AUTH) ? sw_start : sw_argument;
return NGX_OK;
invalid:
@ -583,5 +762,5 @@ invalid:
s->state = sw_start;
s->arg_start = NULL;
return NGX_IMAP_PARSE_INVALID_COMMAND;
return NGX_MAIL_PARSE_INVALID_COMMAND;
}

View File

@ -6,7 +6,7 @@
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_imap.h>
#include <ngx_mail.h>
#define NGX_DEFLAUT_CERTIFICATE "cert.pem"
@ -14,31 +14,31 @@
#define NGX_DEFLAUT_CIPHERS "ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP"
static void *ngx_imap_ssl_create_conf(ngx_conf_t *cf);
static char *ngx_imap_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child);
static char *ngx_imap_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
static void *ngx_mail_ssl_create_conf(ngx_conf_t *cf);
static char *ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child);
static char *ngx_mail_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
#if !defined (SSL_OP_CIPHER_SERVER_PREFERENCE)
static char *ngx_imap_ssl_nosupported(ngx_conf_t *cf, ngx_command_t *cmd,
static char *ngx_mail_ssl_nosupported(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char ngx_imap_ssl_openssl097[] = "OpenSSL 0.9.7 and higher";
static char ngx_mail_ssl_openssl097[] = "OpenSSL 0.9.7 and higher";
#endif
static ngx_conf_enum_t ngx_http_starttls_state[] = {
{ ngx_string("off"), NGX_IMAP_STARTTLS_OFF },
{ ngx_string("on"), NGX_IMAP_STARTTLS_ON },
{ ngx_string("only"), NGX_IMAP_STARTTLS_ONLY },
{ ngx_string("off"), NGX_MAIL_STARTTLS_OFF },
{ ngx_string("on"), NGX_MAIL_STARTTLS_ON },
{ ngx_string("only"), NGX_MAIL_STARTTLS_ONLY },
{ ngx_null_string, 0 }
};
static ngx_conf_bitmask_t ngx_imap_ssl_protocols[] = {
static ngx_conf_bitmask_t ngx_mail_ssl_protocols[] = {
{ ngx_string("SSLv2"), NGX_SSL_SSLv2 },
{ ngx_string("SSLv3"), NGX_SSL_SSLv3 },
{ ngx_string("TLSv1"), NGX_SSL_TLSv1 },
@ -46,93 +46,93 @@ static ngx_conf_bitmask_t ngx_imap_ssl_protocols[] = {
};
static ngx_command_t ngx_imap_ssl_commands[] = {
static ngx_command_t ngx_mail_ssl_commands[] = {
{ ngx_string("ssl"),
NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_FLAG,
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
NGX_IMAP_SRV_CONF_OFFSET,
offsetof(ngx_imap_ssl_conf_t, enable),
NGX_MAIL_SRV_CONF_OFFSET,
offsetof(ngx_mail_ssl_conf_t, enable),
NULL },
{ ngx_string("starttls"),
NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_TAKE1,
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
ngx_conf_set_enum_slot,
NGX_IMAP_SRV_CONF_OFFSET,
offsetof(ngx_imap_ssl_conf_t, starttls),
NGX_MAIL_SRV_CONF_OFFSET,
offsetof(ngx_mail_ssl_conf_t, starttls),
ngx_http_starttls_state },
{ ngx_string("ssl_certificate"),
NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_TAKE1,
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
NGX_IMAP_SRV_CONF_OFFSET,
offsetof(ngx_imap_ssl_conf_t, certificate),
NGX_MAIL_SRV_CONF_OFFSET,
offsetof(ngx_mail_ssl_conf_t, certificate),
NULL },
{ ngx_string("ssl_certificate_key"),
NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_TAKE1,
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
NGX_IMAP_SRV_CONF_OFFSET,
offsetof(ngx_imap_ssl_conf_t, certificate_key),
NGX_MAIL_SRV_CONF_OFFSET,
offsetof(ngx_mail_ssl_conf_t, certificate_key),
NULL },
{ ngx_string("ssl_protocols"),
NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_1MORE,
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
ngx_conf_set_bitmask_slot,
NGX_IMAP_SRV_CONF_OFFSET,
offsetof(ngx_imap_ssl_conf_t, protocols),
&ngx_imap_ssl_protocols },
NGX_MAIL_SRV_CONF_OFFSET,
offsetof(ngx_mail_ssl_conf_t, protocols),
&ngx_mail_ssl_protocols },
{ ngx_string("ssl_ciphers"),
NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_TAKE1,
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
NGX_IMAP_SRV_CONF_OFFSET,
offsetof(ngx_imap_ssl_conf_t, ciphers),
NGX_MAIL_SRV_CONF_OFFSET,
offsetof(ngx_mail_ssl_conf_t, ciphers),
NULL },
{ ngx_string("ssl_prefer_server_ciphers"),
NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_FLAG,
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG,
#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
ngx_conf_set_flag_slot,
NGX_IMAP_SRV_CONF_OFFSET,
offsetof(ngx_imap_ssl_conf_t, prefer_server_ciphers),
NGX_MAIL_SRV_CONF_OFFSET,
offsetof(ngx_mail_ssl_conf_t, prefer_server_ciphers),
NULL },
#else
ngx_imap_ssl_nosupported, 0, 0, ngx_imap_ssl_openssl097 },
ngx_mail_ssl_nosupported, 0, 0, ngx_mail_ssl_openssl097 },
#endif
{ ngx_string("ssl_session_cache"),
NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_TAKE12,
ngx_imap_ssl_session_cache,
NGX_IMAP_SRV_CONF_OFFSET,
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE12,
ngx_mail_ssl_session_cache,
NGX_MAIL_SRV_CONF_OFFSET,
0,
NULL },
{ ngx_string("ssl_session_timeout"),
NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_TAKE1,
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
ngx_conf_set_sec_slot,
NGX_IMAP_SRV_CONF_OFFSET,
offsetof(ngx_imap_ssl_conf_t, session_timeout),
NGX_MAIL_SRV_CONF_OFFSET,
offsetof(ngx_mail_ssl_conf_t, session_timeout),
NULL },
ngx_null_command
};
static ngx_imap_module_t ngx_imap_ssl_module_ctx = {
static ngx_mail_module_t ngx_mail_ssl_module_ctx = {
NULL, /* create main configuration */
NULL, /* init main configuration */
ngx_imap_ssl_create_conf, /* create server configuration */
ngx_imap_ssl_merge_conf /* merge server configuration */
ngx_mail_ssl_create_conf, /* create server configuration */
ngx_mail_ssl_merge_conf /* merge server configuration */
};
ngx_module_t ngx_imap_ssl_module = {
ngx_module_t ngx_mail_ssl_module = {
NGX_MODULE_V1,
&ngx_imap_ssl_module_ctx, /* module context */
ngx_imap_ssl_commands, /* module directives */
NGX_IMAP_MODULE, /* module type */
&ngx_mail_ssl_module_ctx, /* module context */
ngx_mail_ssl_commands, /* module directives */
NGX_MAIL_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
NULL, /* init process */
@ -144,15 +144,15 @@ ngx_module_t ngx_imap_ssl_module = {
};
static ngx_str_t ngx_imap_ssl_sess_id_ctx = ngx_string("IMAP");
static ngx_str_t ngx_mail_ssl_sess_id_ctx = ngx_string("MAIL");
static void *
ngx_imap_ssl_create_conf(ngx_conf_t *cf)
ngx_mail_ssl_create_conf(ngx_conf_t *cf)
{
ngx_imap_ssl_conf_t *scf;
ngx_mail_ssl_conf_t *scf;
scf = ngx_pcalloc(cf->pool, sizeof(ngx_imap_ssl_conf_t));
scf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_ssl_conf_t));
if (scf == NULL) {
return NGX_CONF_ERROR;
}
@ -181,17 +181,17 @@ ngx_imap_ssl_create_conf(ngx_conf_t *cf)
static char *
ngx_imap_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
{
ngx_imap_ssl_conf_t *prev = parent;
ngx_imap_ssl_conf_t *conf = child;
ngx_mail_ssl_conf_t *prev = parent;
ngx_mail_ssl_conf_t *conf = child;
ngx_pool_cleanup_t *cln;
ngx_conf_merge_value(conf->enable, prev->enable, 0);
ngx_conf_merge_value(conf->starttls, prev->starttls, NGX_IMAP_STARTTLS_OFF);
ngx_conf_merge_value(conf->starttls, prev->starttls, NGX_MAIL_STARTTLS_OFF);
if (conf->enable == 0 && conf->starttls == NGX_IMAP_STARTTLS_OFF) {
if (conf->enable == 0 && conf->starttls == NGX_MAIL_STARTTLS_OFF) {
return NGX_CONF_OK;
}
@ -266,7 +266,7 @@ ngx_imap_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
conf->shm_zone = prev->shm_zone;
}
if (ngx_ssl_session_cache(&conf->ssl, &ngx_imap_ssl_sess_id_ctx,
if (ngx_ssl_session_cache(&conf->ssl, &ngx_mail_ssl_sess_id_ctx,
conf->builtin_session_cache,
conf->shm_zone, conf->session_timeout)
!= NGX_OK)
@ -279,9 +279,9 @@ ngx_imap_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
static char *
ngx_imap_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_mail_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_imap_ssl_conf_t *scf = conf;
ngx_mail_ssl_conf_t *scf = conf;
size_t len;
ngx_str_t *value, name, size;
@ -352,7 +352,7 @@ ngx_imap_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
scf->shm_zone = ngx_shared_memory_add(cf, &name, n,
&ngx_imap_ssl_module);
&ngx_mail_ssl_module);
if (scf->shm_zone == NULL) {
return NGX_CONF_ERROR;
}
@ -381,7 +381,7 @@ invalid:
#if !defined (SSL_OP_CIPHER_SERVER_PREFERENCE)
static char *
ngx_imap_ssl_nosupported(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_mail_ssl_nosupported(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"\"%V\" directive is available only in %s,",

View File

@ -4,18 +4,18 @@
*/
#ifndef _NGX_IMAP_SSL_H_INCLUDED_
#define _NGX_IMAP_SSL_H_INCLUDED_
#ifndef _NGX_MAIL_SSL_H_INCLUDED_
#define _NGX_MAIL_SSL_H_INCLUDED_
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_imap.h>
#include <ngx_mail.h>
#define NGX_IMAP_STARTTLS_OFF 0
#define NGX_IMAP_STARTTLS_ON 1
#define NGX_IMAP_STARTTLS_ONLY 2
#define NGX_MAIL_STARTTLS_OFF 0
#define NGX_MAIL_STARTTLS_ON 1
#define NGX_MAIL_STARTTLS_ONLY 2
typedef struct {
@ -38,10 +38,10 @@ typedef struct {
ngx_str_t ciphers;
ngx_shm_zone_t *shm_zone;
} ngx_imap_ssl_conf_t;
} ngx_mail_ssl_conf_t;
extern ngx_module_t ngx_imap_ssl_module;
extern ngx_module_t ngx_mail_ssl_module;
#endif /* _NGX_IMAP_SSL_H_INCLUDED_ */
#endif /* _NGX_MAIL_SSL_H_INCLUDED_ */