# HG changeset patch # User Igor Sysoev # Date 1189875076 0 # Node ID f69493e8faab15a571692076bd1428112fe8621c # Parent 0e7074ef730388318f4b51bc829932718f4990a1 ngx_mail_pop3_module, ngx_mail_imap_module, and ngx_mail_smtp_module diff --git a/auto/modules b/auto/modules --- a/auto/modules +++ b/auto/modules @@ -308,8 +308,6 @@ fi 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 @@ -341,6 +339,26 @@ if [ $MAIL = YES ]; then if [ $MAIL_SSL = YES ]; then modules="$modules $MAIL_SSL_MODULE" + MAIL_DEPS="$MAIL_DEPS $MAIL_SSL_DEPS" + MAIL_SRCS="$MAIL_SRCS $MAIL_SSL_SRCS" + fi + + if [ $MAIL_POP3 = YES ]; then + modules="$modules $MAIL_POP3_MODULE" + MAIL_DEPS="$MAIL_DEPS $MAIL_POP3_DEPS" + MAIL_SRCS="$MAIL_SRCS $MAIL_POP3_SRCS" + fi + + if [ $MAIL_IMAP = YES ]; then + modules="$modules $MAIL_IMAP_MODULE" + MAIL_DEPS="$MAIL_DEPS $MAIL_IMAP_DEPS" + MAIL_SRCS="$MAIL_SRCS $MAIL_IMAP_SRCS" + fi + + if [ $MAIL_SMTP = YES ]; then + modules="$modules $MAIL_SMTP_MODULE" + MAIL_DEPS="$MAIL_DEPS $MAIL_SMTP_DEPS" + MAIL_SRCS="$MAIL_SRCS $MAIL_SMTP_SRCS" fi modules="$modules $MAIL_AUTH_HTTP_MODULE" diff --git a/auto/options b/auto/options --- a/auto/options +++ b/auto/options @@ -81,6 +81,9 @@ HTTP_STUB_STATUS=NO MAIL=NO MAIL_SSL=NO +MAIL_POP3=YES +MAIL_IMAP=YES +MAIL_SMTP=YES NGX_ADDONS= @@ -190,6 +193,9 @@ do # STUB --with-imap) MAIL=YES ;; --with-imap_ssl_module) MAIL_SSL=YES ;; + --without-mail_pop3_module) MAIL_POP3=NO ;; + --without-mail_imap_module) MAIL_IMAP=NO ;; + --without-mail_smtp_module) MAIL_SMTP=NO ;; --add-module=*) NGX_ADDONS="$NGX_ADDONS $value" ;; diff --git a/auto/sources b/auto/sources --- a/auto/sources +++ b/auto/sources @@ -423,11 +423,23 @@ MAIL_MODULES="ngx_mail_module ngx_mail_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_pop3_handler.c \ - src/mail/ngx_mail_imap_handler.c \ - src/mail/ngx_mail_smtp_handler.c \ src/mail/ngx_mail_parse.c" +MAIL_POP3_MODULE="ngx_mail_pop3_module" +MAIL_POP3_DEPS="src/mail/ngx_mail_pop3_module.h" +MAIL_POP3_SRCS="src/mail/ngx_mail_pop3_module.c \ + src/mail/ngx_mail_pop3_handler.c" + +MAIL_IMAP_MODULE="ngx_mail_imap_module" +MAIL_IMAP_DEPS="src/mail/ngx_mail_imap_module.h" +MAIL_IMAP_SRCS="src/mail/ngx_mail_imap_module.c \ + src/mail/ngx_mail_imap_handler.c" + +MAIL_SMTP_MODULE="ngx_mail_smtp_module" +MAIL_SMTP_DEPS="src/mail/ngx_mail_smtp_module.h" +MAIL_SMTP_SRCS="src/mail/ngx_mail_smtp_module.c \ + src/mail/ngx_mail_smtp_handler.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" diff --git a/src/mail/ngx_mail.c b/src/mail/ngx_mail.c --- a/src/mail/ngx_mail.c +++ b/src/mail/ngx_mail.c @@ -185,6 +185,8 @@ ngx_mail_block(ngx_conf_t *cf, ngx_comma /* init mail{} main_conf's */ + cf->ctx = ctx; + if (module->init_main_conf) { rv = module->init_main_conf(cf, ctx->main_conf[mi]); if (rv != NGX_CONF_OK) { @@ -197,6 +199,8 @@ ngx_mail_block(ngx_conf_t *cf, ngx_comma /* merge the server{}s' srv_conf's */ + cf->ctx = cscfp[s]->ctx; + if (module->merge_srv_conf) { rv = module->merge_srv_conf(cf, ctx->srv_conf[mi], @@ -209,8 +213,6 @@ ngx_mail_block(ngx_conf_t *cf, ngx_comma } } - /* mail{}'s cf->ctx was needed while the configuration merging */ - *cf = pcf; diff --git a/src/mail/ngx_mail.h b/src/mail/ngx_mail.h --- a/src/mail/ngx_mail.h +++ b/src/mail/ngx_mail.h @@ -73,57 +73,27 @@ typedef struct { #define NGX_MAIL_IMAP_PROTOCOL 1 #define NGX_MAIL_SMTP_PROTOCOL 2 -typedef struct { - ngx_msec_t timeout; - ngx_msec_t smtp_greeting_delay; + +typedef struct ngx_mail_protocol_s ngx_mail_protocol_t; + - size_t imap_client_buffer_size; - size_t smtp_client_buffer_size; +typedef struct { + ngx_mail_protocol_t *protocol; - ngx_uint_t protocol; + ngx_msec_t timeout; ngx_flag_t so_keepalive; - 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_str_t smtp_starttls_capability; - ngx_str_t smtp_starttls_only_capability; - - 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 imap_auth_methods; - ngx_uint_t smtp_auth_methods; - - ngx_array_t pop3_capabilities; - ngx_array_t imap_capabilities; - ngx_array_t smtp_capabilities; + u_char *file_name; + ngx_int_t line; /* server ctx */ ngx_mail_conf_ctx_t *ctx; } ngx_mail_core_srv_conf_t; -typedef struct { - void *(*create_main_conf)(ngx_conf_t *cf); - char *(*init_main_conf)(ngx_conf_t *cf, void *conf); - - void *(*create_srv_conf)(ngx_conf_t *cf); - char *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, - void *conf); -} ngx_mail_module_t; - - typedef enum { ngx_pop3_start = 0, ngx_pop3_user, @@ -181,9 +151,9 @@ typedef struct { ngx_uint_t mail_state; + unsigned protocol:3; unsigned blocked:1; unsigned quit:1; - unsigned protocol:2; unsigned quoted:1; unsigned backslash:1; unsigned no_sync_literal:1; @@ -208,7 +178,7 @@ typedef struct { ngx_uint_t login_attempt; - /* used to parse IMAP/POP3/SMTP command */ + /* used to parse POP3/IMAP/SMTP command */ ngx_uint_t state; u_char *cmd_start; @@ -282,10 +252,43 @@ typedef struct { #define NGX_MAIL_PARSE_INVALID_COMMAND 20 -#define NGX_MAIL_MODULE 0x4C49414D /* "MAIL" */ +typedef void (*ngx_mail_init_session_pt)(ngx_mail_session_t *s, + ngx_connection_t *c); +typedef void (*ngx_mail_init_protocol_pt)(ngx_event_t *rev); +typedef void (*ngx_mail_auth_state_pt)(ngx_event_t *rev); +typedef ngx_int_t (*ngx_mail_parse_command_pt)(ngx_mail_session_t *s); + + +struct ngx_mail_protocol_s { + ngx_str_t name; + in_port_t port[4]; + ngx_uint_t type; + + ngx_mail_init_session_pt init_session; + ngx_mail_init_protocol_pt init_protocol; + ngx_mail_parse_command_pt parse_command; + ngx_mail_auth_state_pt auth_state; -#define NGX_MAIL_MAIN_CONF 0x02000000 -#define NGX_MAIL_SRV_CONF 0x04000000 + ngx_str_t internal_server_error; +}; + + +typedef struct { + ngx_mail_protocol_t *protocol; + + void *(*create_main_conf)(ngx_conf_t *cf); + char *(*init_main_conf)(ngx_conf_t *cf, void *conf); + + void *(*create_srv_conf)(ngx_conf_t *cf); + char *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, + void *conf); +} ngx_mail_module_t; + + +#define NGX_MAIL_MODULE 0x4C49414D /* "MAIL" */ + +#define NGX_MAIL_MAIN_CONF 0x02000000 +#define NGX_MAIL_SRV_CONF 0x04000000 #define NGX_MAIL_MAIN_CONF_OFFSET offsetof(ngx_mail_conf_ctx_t, main_conf) @@ -306,12 +309,6 @@ typedef struct { #define ngx_mail_conf_get_module_srv_conf(cf, module) \ ((ngx_mail_conf_ctx_t *) cf->ctx)->srv_conf[module.ctx_index] -typedef void (*ngx_mail_init_session_pt)(ngx_mail_session_t *s, - ngx_connection_t *c); -typedef void (*ngx_mail_init_protocol_pt)(ngx_event_t *rev); -typedef void (*ngx_mail_auth_state_pt)(ngx_event_t *rev); -typedef ngx_int_t (*ngx_mail_parse_command_pt)(ngx_mail_session_t *s); - #if (NGX_MAIL_SSL) void ngx_mail_starttls_handler(ngx_event_t *rev); @@ -321,10 +318,6 @@ ngx_int_t ngx_mail_starttls_only(ngx_mai void ngx_mail_init_connection(ngx_connection_t *c); -void ngx_mail_pop3_auth_state(ngx_event_t *rev); -void ngx_mail_imap_auth_state(ngx_event_t *rev); -void ngx_mail_smtp_auth_state(ngx_event_t *rev); - ngx_int_t ngx_mail_salt(ngx_mail_session_t *s, ngx_connection_t *c, ngx_mail_core_srv_conf_t *cscf); ngx_int_t ngx_mail_auth_plain(ngx_mail_session_t *s, ngx_connection_t *c, @@ -336,6 +329,7 @@ ngx_int_t ngx_mail_auth_login_password(n ngx_int_t ngx_mail_auth_cram_md5_salt(ngx_mail_session_t *s, ngx_connection_t *c, char *prefix, size_t len); ngx_int_t ngx_mail_auth_cram_md5(ngx_mail_session_t *s, ngx_connection_t *c); +ngx_int_t ngx_mail_auth_parse(ngx_mail_session_t *s, ngx_connection_t *c); void ngx_mail_send(ngx_event_t *wev); ngx_int_t ngx_mail_read_command(ngx_mail_session_t *s, ngx_connection_t *c); @@ -345,18 +339,7 @@ void ngx_mail_session_internal_server_er u_char *ngx_mail_log_error(ngx_log_t *log, u_char *buf, size_t len); -void ngx_mail_pop3_init_session(ngx_mail_session_t *s, ngx_connection_t *c); -void ngx_mail_imap_init_session(ngx_mail_session_t *s, ngx_connection_t *c); -void ngx_mail_smtp_init_session(ngx_mail_session_t *s, ngx_connection_t *c); - -void ngx_mail_pop3_init_protocol(ngx_event_t *rev); -void ngx_mail_imap_init_protocol(ngx_event_t *rev); -void ngx_mail_smtp_init_protocol(ngx_event_t *rev); - -ngx_int_t ngx_mail_pop3_parse_command(ngx_mail_session_t *s); -ngx_int_t ngx_mail_imap_parse_command(ngx_mail_session_t *s); -ngx_int_t ngx_mail_smtp_parse_command(ngx_mail_session_t *s); -ngx_int_t ngx_mail_auth_parse(ngx_mail_session_t *s, ngx_connection_t *c); +char *ngx_mail_capabilities(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); /* STUB */ diff --git a/src/mail/ngx_mail_auth_http_module.c b/src/mail/ngx_mail_auth_http_module.c --- a/src/mail/ngx_mail_auth_http_module.c +++ b/src/mail/ngx_mail_auth_http_module.c @@ -111,6 +111,8 @@ static ngx_command_t ngx_mail_auth_http static ngx_mail_module_t ngx_mail_auth_http_module_ctx = { + NULL, /* protocol */ + NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -135,7 +137,6 @@ ngx_module_t ngx_mail_auth_http_module }; -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"), @@ -145,18 +146,6 @@ static ngx_str_t ngx_mail_auth_http_me static ngx_str_t ngx_mail_smtp_errcode = ngx_string("535 5.7.0"); -static ngx_uint_t ngx_mail_start_states[] = { - ngx_pop3_start, - ngx_imap_start, - ngx_smtp_start -}; - -static ngx_mail_auth_state_pt ngx_mail_auth_states[] = { - ngx_mail_pop3_auth_state, - ngx_mail_imap_auth_state, - ngx_mail_smtp_auth_state -}; - void ngx_mail_auth_http_init(ngx_mail_session_t *s) @@ -762,7 +751,8 @@ ngx_mail_auth_http_process_headers(ngx_m return; } - if (s->passwd.data == NULL && s->protocol != NGX_MAIL_SMTP_PROTOCOL) + 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", @@ -881,9 +871,11 @@ ngx_mail_auth_sleep_handler(ngx_event_t return; } - s->mail_state = ngx_mail_start_states[s->protocol]; - rev->handler = ngx_mail_auth_states[s->protocol]; + cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); + rev->handler = cscf->protocol->auth_state; + + s->mail_state = 0; s->auth_method = NGX_MAIL_AUTH_PLAIN; c->log->action = "in auth state"; @@ -894,8 +886,6 @@ ngx_mail_auth_sleep_handler(ngx_event_t return; } - cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); - ngx_add_timer(rev, cscf->timeout); if (rev->ready) { @@ -1145,9 +1135,10 @@ 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) { - size_t len; - ngx_buf_t *b; - ngx_str_t login, passwd; + size_t len; + ngx_buf_t *b; + ngx_str_t login, passwd; + ngx_mail_core_srv_conf_t *cscf; if (ngx_mail_auth_http_escape(pool, &s->login, &login) != NGX_OK) { return NULL; @@ -1157,6 +1148,8 @@ ngx_mail_auth_http_create_request(ngx_ma return NULL; } + cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); + 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 @@ -1165,7 +1158,8 @@ ngx_mail_auth_http_create_request(ngx_ma + sizeof("Auth-User: ") - 1 + login.len + sizeof(CRLF) - 1 + sizeof("Auth-Pass: ") - 1 + passwd.len + sizeof(CRLF) - 1 + sizeof("Auth-Salt: ") - 1 + s->salt.len - + sizeof("Auth-Protocol: imap" CRLF) - 1 + + sizeof("Auth-Protocol: ") - 1 + cscf->protocol->name.len + + sizeof(CRLF) - 1 + sizeof("Auth-Login-Attempt: ") - 1 + NGX_INT_T_LEN + sizeof(CRLF) - 1 + sizeof("Client-IP: ") - 1 + s->connection->addr_text.len @@ -1212,8 +1206,8 @@ ngx_mail_auth_http_create_request(ngx_ma b->last = ngx_cpymem(b->last, "Auth-Protocol: ", sizeof("Auth-Protocol: ") - 1); - b->last = ngx_cpymem(b->last, ngx_mail_auth_http_protocol[s->protocol], - sizeof("imap") - 1); + b->last = ngx_cpymem(b->last, cscf->protocol->name.data, + cscf->protocol->name.len); *b->last++ = CR; *b->last++ = LF; b->last = ngx_sprintf(b->last, "Auth-Login-Attempt: %ui" CRLF, diff --git a/src/mail/ngx_mail_core_module.c b/src/mail/ngx_mail_core_module.c --- a/src/mail/ngx_mail_core_module.c +++ b/src/mail/ngx_mail_core_module.c @@ -18,90 +18,10 @@ static char *ngx_mail_core_server(ngx_co void *conf); static char *ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); -static char *ngx_mail_core_capability(ngx_conf_t *cf, ngx_command_t *cmd, +static char *ngx_mail_core_protocol(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); -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 } -}; - - -static ngx_str_t ngx_pop3_default_capabilities[] = { - ngx_string("TOP"), - ngx_string("USER"), - ngx_string("UIDL"), - ngx_null_string -}; - - -static ngx_str_t ngx_imap_default_capabilities[] = { - ngx_string("IMAP4"), - ngx_string("IMAP4rev1"), - ngx_string("UIDPLUS"), - ngx_null_string -}; - - -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_imap_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_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_imap_auth_methods_names[] = { - ngx_string("AUTH=PLAIN"), - ngx_string("AUTH=LOGIN"), - ngx_null_string, /* APOP */ - ngx_string("AUTH=CRAM-MD5") -}; - - -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 - "PLAIN" CRLF - "." CRLF); - - -static ngx_str_t ngx_pop3_auth_cram_md5_capability = - ngx_string("+OK methods supported:" CRLF - "LOGIN" CRLF - "PLAIN" CRLF - "CRAM-MD5" CRLF - "." CRLF); - - - static ngx_command_t ngx_mail_core_commands[] = { { ngx_string("server"), @@ -114,36 +34,15 @@ static ngx_command_t ngx_mail_core_comm { ngx_string("listen"), NGX_MAIL_SRV_CONF|NGX_CONF_TAKE12, ngx_mail_core_listen, - 0, + NGX_MAIL_SRV_CONF_OFFSET, 0, NULL }, { ngx_string("protocol"), NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_enum_slot, - NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_core_srv_conf_t, protocol), - &ngx_mail_core_procotol }, - - { ngx_string("imap_client_buffer"), - NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_size_slot, + ngx_mail_core_protocol, NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_core_srv_conf_t, imap_client_buffer_size), - NULL }, - - { ngx_string("smtp_client_buffer"), - NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_size_slot, - NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_core_srv_conf_t, smtp_client_buffer_size), - NULL }, - - { ngx_string("smtp_greeting_delay"), - NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_msec_slot, - NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_core_srv_conf_t, smtp_greeting_delay), + 0, NULL }, { ngx_string("so_keepalive"), @@ -160,27 +59,6 @@ static ngx_command_t ngx_mail_core_comm offsetof(ngx_mail_core_srv_conf_t, timeout), NULL }, - { ngx_string("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_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_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, ngx_conf_set_str_slot, @@ -188,39 +66,13 @@ static ngx_command_t ngx_mail_core_comm offsetof(ngx_mail_core_srv_conf_t, server_name), NULL }, - { ngx_string("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("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("imap_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, imap_auth_methods), - &ngx_imap_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_mail_module_t ngx_mail_core_module_ctx = { + NULL, /* protocol */ + ngx_mail_core_create_main_conf, /* create main configuration */ NULL, /* init main configuration */ @@ -282,30 +134,14 @@ ngx_mail_core_create_srv_conf(ngx_conf_t return NULL; } - cscf->imap_client_buffer_size = NGX_CONF_UNSET_SIZE; - cscf->smtp_client_buffer_size = NGX_CONF_UNSET_SIZE; - cscf->protocol = NGX_CONF_UNSET_UINT; - cscf->timeout = NGX_CONF_UNSET_MSEC; - cscf->smtp_greeting_delay = NGX_CONF_UNSET_MSEC; - cscf->so_keepalive = NGX_CONF_UNSET; + /* + * set by ngx_pcalloc(): + * + * cscf->protocol = NULL; + */ - if (ngx_array_init(&cscf->pop3_capabilities, cf->pool, 4, sizeof(ngx_str_t)) - != NGX_OK) - { - return NULL; - } - - if (ngx_array_init(&cscf->imap_capabilities, cf->pool, 4, sizeof(ngx_str_t)) - != NGX_OK) - { - return NULL; - } - - if (ngx_array_init(&cscf->smtp_capabilities, cf->pool, 4, sizeof(ngx_str_t)) - != NGX_OK) - { - return NULL; - } + cscf->timeout = NGX_CONF_UNSET_MSEC; + cscf->so_keepalive = NGX_CONF_UNSET; return cscf; } @@ -317,42 +153,10 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t ngx_mail_core_srv_conf_t *prev = parent; ngx_mail_core_srv_conf_t *conf = child; - u_char *p, *auth; - size_t size, stls_only_size; - ngx_str_t *c, *d; - 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_size_value(conf->smtp_client_buffer_size, - prev->smtp_client_buffer_size, - (size_t) ngx_pagesize); - ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 60000); - ngx_conf_merge_msec_value(conf->smtp_greeting_delay, - prev->smtp_greeting_delay, 0); - ngx_conf_merge_uint_value(conf->protocol, prev->protocol, - NGX_MAIL_IMAP_PROTOCOL); ngx_conf_merge_value(conf->so_keepalive, prev->so_keepalive, 0); - 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->imap_auth_methods, - prev->imap_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, ""); @@ -365,351 +169,21 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t if (gethostname((char *) conf->server_name.data, NGX_MAXHOSTNAMELEN) == -1) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno, - "gethostname() failed"); + ngx_log_error(NGX_LOG_EMERG, cf->log, ngx_errno, + "gethostname() failed"); return NGX_CONF_ERROR; } conf->server_name.len = ngx_strlen(conf->server_name.data); } - - if (conf->pop3_capabilities.nelts == 0) { - conf->pop3_capabilities = prev->pop3_capabilities; - } - - if (conf->pop3_capabilities.nelts == 0) { - - for (d = ngx_pop3_default_capabilities; d->len; d++) { - c = ngx_array_push(&conf->pop3_capabilities); - if (c == NULL) { - return NGX_CONF_ERROR; - } - - *c = *d; - } - } - - 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->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) { - size += sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1; - - } else { - size += sizeof("SASL LOGIN PLAIN" CRLF) - 1; - } - - p = ngx_palloc(cf->pool, size); - if (p == NULL) { - return NGX_CONF_ERROR; - } - - conf->pop3_capability.len = size; - conf->pop3_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++) { - p = ngx_cpymem(p, c[i].data, c[i].len); - *p++ = CR; *p++ = LF; - } - - 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); - - } else { - p = ngx_cpymem(p, "SASL LOGIN PLAIN" CRLF, - sizeof("SASL LOGIN PLAIN" CRLF) - 1); - } - - *p++ = '.'; *p++ = CR; *p = LF; - - - size += sizeof("STLS" CRLF) - 1; - - p = ngx_palloc(cf->pool, size); - if (p == NULL) { - return NGX_CONF_ERROR; - } - - conf->pop3_starttls_capability.len = size; - conf->pop3_starttls_capability.data = p; - - p = ngx_cpymem(p, conf->pop3_capability.data, - conf->pop3_capability.len - (sizeof("." CRLF) - 1)); - - p = ngx_cpymem(p, "STLS" CRLF, sizeof("STLS" CRLF) - 1); - *p++ = '.'; *p++ = CR; *p = LF; - - - if (conf->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) { - conf->pop3_auth_capability = ngx_pop3_auth_cram_md5_capability; - - } else { - conf->pop3_auth_capability = ngx_pop3_auth_plain_capability; - } - - - 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; - } - - if (conf->imap_capabilities.nelts == 0) { - - for (d = ngx_imap_default_capabilities; d->len; d++) { - c = ngx_array_push(&conf->imap_capabilities); - if (c == NULL) { - return NGX_CONF_ERROR; - } - - *c = *d; - } - } - - size = sizeof("* CAPABILITY" CRLF) - 1; - - c = conf->imap_capabilities.elts; - for (i = 0; i < conf->imap_capabilities.nelts; i++) { - size += 1 + c[i].len; - } - - for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; - m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; - m <<= 1, i++) - { - if (m & conf->imap_auth_methods) { - size += 1 + ngx_imap_auth_methods_names[i].len; - } - } - - p = ngx_palloc(cf->pool, size); - if (p == NULL) { + if (conf->protocol == NULL) { + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, + "unknown mail protocol for server in %s:%ui", + conf->file_name, conf->line); return NGX_CONF_ERROR; } - conf->imap_capability.len = size; - conf->imap_capability.data = p; - - p = ngx_cpymem(p, "* CAPABILITY", sizeof("* CAPABILITY") - 1); - - for (i = 0; i < conf->imap_capabilities.nelts; i++) { - *p++ = ' '; - p = ngx_cpymem(p, c[i].data, c[i].len); - } - - auth = p; - - for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; - m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; - m <<= 1, i++) - { - if (m & conf->imap_auth_methods) { - *p++ = ' '; - p = ngx_cpymem(p, ngx_imap_auth_methods_names[i].data, - ngx_imap_auth_methods_names[i].len); - } - } - - *p++ = CR; *p = LF; - - - size += sizeof(" STARTTLS") - 1; - - p = ngx_palloc(cf->pool, size); - if (p == NULL) { - return NGX_CONF_ERROR; - } - - conf->imap_starttls_capability.len = size; - conf->imap_starttls_capability.data = p; - - p = ngx_cpymem(p, conf->imap_capability.data, - conf->imap_capability.len - (sizeof(CRLF) - 1)); - p = ngx_cpymem(p, " STARTTLS", sizeof(" STARTTLS") - 1); - *p++ = CR; *p = LF; - - - size = (auth - conf->imap_capability.data) + sizeof(CRLF) - 1 - + sizeof(" STARTTLS LOGINDISABLED") - 1; - - p = ngx_palloc(cf->pool, size); - if (p == NULL) { - return NGX_CONF_ERROR; - } - - conf->imap_starttls_only_capability.len = size; - conf->imap_starttls_only_capability.data = p; - - p = ngx_cpymem(p, conf->imap_capability.data, - auth - conf->imap_capability.data); - p = ngx_cpymem(p, " STARTTLS LOGINDISABLED", - sizeof(" STARTTLS LOGINDISABLED") - 1); - *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; - } - - auth = p; - - *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; - - size += sizeof("250 STARTTLS" CRLF) - 1; - - p = ngx_palloc(cf->pool, size); - if (p == NULL) { - return NGX_CONF_ERROR; - } - - conf->smtp_starttls_capability.len = size; - conf->smtp_starttls_capability.data = p; - - p = ngx_cpymem(p, conf->smtp_capability.data, - conf->smtp_capability.len); - - p = ngx_cpymem(p, "250 STARTTLS" CRLF, sizeof("250 STARTTLS" CRLF) - 1); - *p++ = CR; *p = LF; - - p = conf->smtp_starttls_capability.data - + (auth - conf->smtp_capability.data) + 3; - *p = '-'; - - size = (auth - conf->smtp_capability.data) - + sizeof("250 STARTTLS" CRLF) - 1; - - p = ngx_palloc(cf->pool, size); - if (p == NULL) { - return NGX_CONF_ERROR; - } - - conf->smtp_starttls_only_capability.len = size; - conf->smtp_starttls_only_capability.data = p; - - p = ngx_cpymem(p, conf->smtp_capability.data, - auth - conf->smtp_capability.data); - - ngx_memcpy(p, "250 STARTTLS" CRLF, sizeof("250 STARTTLS" CRLF) - 1); - return NGX_CONF_OK; } @@ -726,7 +200,6 @@ ngx_mail_core_server(ngx_conf_t *cf, ngx ngx_mail_core_srv_conf_t *cscf, **cscfp; ngx_mail_core_main_conf_t *cmcf; - ctx = ngx_pcalloc(cf->pool, sizeof(ngx_mail_conf_ctx_t)); if (ctx == NULL) { return NGX_CONF_ERROR; @@ -764,6 +237,9 @@ ngx_mail_core_server(ngx_conf_t *cf, ngx cscf = ctx->srv_conf[ngx_mail_core_module.ctx_index]; cscf->ctx = ctx; + cscf->file_name = cf->conf_file->file.name.data; + cscf->line = cf->conf_file->line; + cmcf = ctx->main_conf[ngx_mail_core_module.ctx_index]; cscfp = ngx_array_push(&cmcf->servers); @@ -793,10 +269,13 @@ ngx_mail_core_server(ngx_conf_t *cf, ngx static char * ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { + ngx_mail_core_srv_conf_t *cscf = conf; + ngx_str_t *value; ngx_url_t u; - ngx_uint_t i; + ngx_uint_t i, m; ngx_mail_listen_t *imls; + ngx_mail_module_t *module; ngx_mail_core_main_conf_t *cmcf; value = cf->args->elts; @@ -843,6 +322,25 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx imls->family = AF_INET; imls->ctx = cf->ctx; + for (m = 0; ngx_modules[m]; m++) { + if (ngx_modules[m]->type != NGX_MAIL_MODULE) { + continue; + } + + module = ngx_modules[m]->ctx; + + if (module->protocol == NULL) { + continue; + } + + for (i = 0; module->protocol->port[i]; i++) { + if (module->protocol->port[i] == u.port) { + cscf->protocol = module->protocol; + break; + } + } + } + if (cf->args->nelts == 2) { return NGX_CONF_OK; } @@ -859,7 +357,40 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx static char * -ngx_mail_core_capability(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +ngx_mail_core_protocol(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_mail_core_srv_conf_t *cscf = conf; + + ngx_str_t *value; + ngx_uint_t m; + ngx_mail_module_t *module; + + value = cf->args->elts; + + for (m = 0; ngx_modules[m]; m++) { + if (ngx_modules[m]->type != NGX_MAIL_MODULE) { + continue; + } + + module = ngx_modules[m]->ctx; + + if (module->protocol + && ngx_strcmp(module->protocol->name.data, value[1].data) == 0) + { + cscf->protocol = module->protocol; + + return NGX_CONF_OK; + } + } + + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "unknown protocol \"%V\"", &value[1]); + return NGX_CONF_ERROR; +} + + +char * +ngx_mail_capabilities(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { char *p = conf; diff --git a/src/mail/ngx_mail_handler.c b/src/mail/ngx_mail_handler.c --- a/src/mail/ngx_mail_handler.c +++ b/src/mail/ngx_mail_handler.c @@ -18,34 +18,6 @@ static void ngx_mail_ssl_handshake_handl #endif -static ngx_mail_init_session_pt ngx_mail_init_sessions[] = { - ngx_mail_pop3_init_session, - ngx_mail_imap_init_session, - ngx_mail_smtp_init_session -}; - - -static ngx_mail_init_protocol_pt ngx_mail_init_protocols[] = { - ngx_mail_pop3_init_protocol, - ngx_mail_imap_init_protocol, - ngx_mail_smtp_init_protocol -}; - - -static ngx_mail_parse_command_pt ngx_mail_parse_commands[] = { - ngx_mail_pop3_parse_command, - ngx_mail_imap_parse_command, - ngx_mail_smtp_parse_command -}; - - -static ngx_str_t internal_server_errors[] = { - ngx_string("-ERR internal server error" CRLF), - ngx_string("* BAD internal server error" CRLF), - ngx_string("451 4.3.2 Internal server error" CRLF), -}; - - void ngx_mail_init_connection(ngx_connection_t *c) { @@ -210,17 +182,20 @@ ngx_mail_ssl_init_connection(ngx_ssl_t * static void ngx_mail_ssl_handshake_handler(ngx_connection_t *c) { - ngx_mail_session_t *s; + ngx_mail_session_t *s; + ngx_mail_core_srv_conf_t *cscf; if (c->ssl->handshaked) { s = c->data; if (s->starttls) { - c->read->handler = ngx_mail_init_protocols[s->protocol]; + cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); + + c->read->handler = cscf->protocol->init_protocol; c->write->handler = ngx_mail_send; - ngx_mail_init_protocols[s->protocol](c->read); + cscf->protocol->init_protocol(c->read); return; } @@ -245,7 +220,7 @@ ngx_mail_init_session(ngx_connection_t * cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); - s->protocol = cscf->protocol; + s->protocol = cscf->protocol->type; s->ctx = ngx_pcalloc(c->pool, sizeof(void *) * ngx_mail_max_module); if (s->ctx == NULL) { @@ -255,7 +230,7 @@ ngx_mail_init_session(ngx_connection_t * c->write->handler = ngx_mail_send; - ngx_mail_init_sessions[s->protocol](s, c); + cscf->protocol->init_session(s, c); } @@ -567,9 +542,10 @@ ngx_mail_send(ngx_event_t *wev) ngx_int_t ngx_mail_read_command(ngx_mail_session_t *s, ngx_connection_t *c) { - ssize_t n; - ngx_int_t rc; - ngx_str_t l; + ssize_t n; + ngx_int_t rc; + ngx_str_t l; + ngx_mail_core_srv_conf_t *cscf; n = c->recv(c, s->buffer->last, s->buffer->end - s->buffer->last); @@ -591,7 +567,9 @@ ngx_mail_read_command(ngx_mail_session_t return NGX_AGAIN; } - rc = ngx_mail_parse_commands[s->protocol](s); + cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); + + rc = cscf->protocol->parse_command(s); if (rc == NGX_AGAIN) { @@ -644,7 +622,11 @@ ngx_mail_auth(ngx_mail_session_t *s, ngx void ngx_mail_session_internal_server_error(ngx_mail_session_t *s) { - s->out = internal_server_errors[s->protocol]; + ngx_mail_core_srv_conf_t *cscf; + + cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); + + s->out = cscf->protocol->internal_server_error; s->quit = 1; ngx_mail_send(s->connection->write); diff --git a/src/mail/ngx_mail_imap_handler.c b/src/mail/ngx_mail_imap_handler.c --- a/src/mail/ngx_mail_imap_handler.c +++ b/src/mail/ngx_mail_imap_handler.c @@ -8,6 +8,7 @@ #include #include #include +#include static ngx_int_t ngx_mail_imap_login(ngx_mail_session_t *s, @@ -58,7 +59,7 @@ ngx_mail_imap_init_protocol(ngx_event_t { ngx_connection_t *c; ngx_mail_session_t *s; - ngx_mail_core_srv_conf_t *cscf; + ngx_mail_imap_srv_conf_t *iscf; c = rev->data; @@ -81,9 +82,9 @@ ngx_mail_imap_init_protocol(ngx_event_t return; } - cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); + iscf = ngx_mail_get_module_srv_conf(s, ngx_mail_imap_module); - s->buffer = ngx_create_temp_buf(c->pool, cscf->imap_client_buffer_size); + s->buffer = ngx_create_temp_buf(c->pool, iscf->client_buffer_size); if (s->buffer == NULL) { ngx_mail_session_internal_server_error(s); return; @@ -349,6 +350,7 @@ ngx_mail_imap_authenticate(ngx_mail_sess { ngx_int_t rc; ngx_mail_core_srv_conf_t *cscf; + ngx_mail_imap_srv_conf_t *iscf; #if (NGX_MAIL_SSL) if (ngx_mail_starttls_only(s, c)) { @@ -378,13 +380,15 @@ ngx_mail_imap_authenticate(ngx_mail_sess case NGX_MAIL_AUTH_CRAM_MD5: - cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); + iscf = ngx_mail_get_module_srv_conf(s, ngx_mail_imap_module); - if (!(cscf->imap_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED)) { + if (!(iscf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED)) { return NGX_MAIL_PARSE_INVALID_COMMAND; } if (s->salt.data == NULL) { + cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); + if (ngx_mail_salt(s, c, cscf) != NGX_OK) { return NGX_ERROR; } @@ -405,12 +409,12 @@ ngx_mail_imap_authenticate(ngx_mail_sess static ngx_int_t ngx_mail_imap_capability(ngx_mail_session_t *s, ngx_connection_t *c) { - ngx_mail_core_srv_conf_t *cscf; + ngx_mail_imap_srv_conf_t *iscf; #if (NGX_MAIL_SSL) ngx_mail_ssl_conf_t *sslcf; #endif - cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); + iscf = ngx_mail_get_module_srv_conf(s, ngx_mail_imap_module); #if (NGX_MAIL_SSL) @@ -418,18 +422,18 @@ ngx_mail_imap_capability(ngx_mail_sessio sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module); if (sslcf->starttls == NGX_MAIL_STARTTLS_ON) { - s->text = cscf->imap_starttls_capability; + s->text = iscf->starttls_capability; return NGX_OK; } if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) { - s->text = cscf->imap_starttls_only_capability; + s->text = iscf->starttls_only_capability; return NGX_OK; } } #endif - s->text = cscf->imap_capability; + s->text = iscf->capability; return NGX_OK; } diff --git a/src/mail/ngx_mail_core_module.c b/src/mail/ngx_mail_imap_module.c copy from src/mail/ngx_mail_core_module.c copy to src/mail/ngx_mail_imap_module.c --- a/src/mail/ngx_mail_core_module.c +++ b/src/mail/ngx_mail_imap_module.c @@ -8,37 +8,15 @@ #include #include #include - - -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_mail_core_server(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -static char *ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -static char *ngx_mail_core_capability(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); +#include -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 } -}; +static void *ngx_mail_imap_create_srv_conf(ngx_conf_t *cf); +static char *ngx_mail_imap_merge_srv_conf(ngx_conf_t *cf, void *parent, + void *child); -static ngx_str_t ngx_pop3_default_capabilities[] = { - ngx_string("TOP"), - ngx_string("USER"), - ngx_string("UIDL"), - ngx_null_string -}; - - -static ngx_str_t ngx_imap_default_capabilities[] = { +static ngx_str_t ngx_mail_imap_default_capabilities[] = { ngx_string("IMAP4"), ngx_string("IMAP4rev1"), ngx_string("UIDPLUS"), @@ -46,15 +24,7 @@ static ngx_str_t ngx_imap_default_capab }; -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_imap_auth_methods[] = { +static ngx_conf_bitmask_t ngx_mail_imap_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 }, @@ -62,15 +32,7 @@ static ngx_conf_bitmask_t ngx_imap_auth }; -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_imap_auth_methods_names[] = { +static ngx_str_t ngx_mail_imap_auth_methods_names[] = { ngx_string("AUTH=PLAIN"), ngx_string("AUTH=LOGIN"), ngx_null_string, /* APOP */ @@ -78,161 +40,62 @@ static ngx_str_t ngx_imap_auth_methods_ }; -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_mail_protocol_t ngx_mail_imap_protocol = { + ngx_string("imap"), + { 143, 993, 0, 0 }, + NGX_MAIL_IMAP_PROTOCOL, + + ngx_mail_imap_init_session, + ngx_mail_imap_init_protocol, + ngx_mail_imap_parse_command, + ngx_mail_imap_auth_state, + + ngx_string("* BAD internal server error" CRLF) }; -static ngx_str_t ngx_pop3_auth_plain_capability = - ngx_string("+OK methods supported:" CRLF - "LOGIN" CRLF - "PLAIN" CRLF - "." CRLF); - - -static ngx_str_t ngx_pop3_auth_cram_md5_capability = - ngx_string("+OK methods supported:" CRLF - "LOGIN" CRLF - "PLAIN" CRLF - "CRAM-MD5" CRLF - "." CRLF); - - - -static ngx_command_t ngx_mail_core_commands[] = { - - { ngx_string("server"), - NGX_MAIL_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, - ngx_mail_core_server, - 0, - 0, - NULL }, - - { ngx_string("listen"), - NGX_MAIL_SRV_CONF|NGX_CONF_TAKE12, - ngx_mail_core_listen, - 0, - 0, - NULL }, - - { ngx_string("protocol"), - NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_enum_slot, - NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_core_srv_conf_t, protocol), - &ngx_mail_core_procotol }, +static ngx_command_t ngx_mail_imap_commands[] = { { ngx_string("imap_client_buffer"), NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, ngx_conf_set_size_slot, NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_core_srv_conf_t, imap_client_buffer_size), - NULL }, - - { ngx_string("smtp_client_buffer"), - NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_size_slot, - NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_core_srv_conf_t, smtp_client_buffer_size), - NULL }, - - { ngx_string("smtp_greeting_delay"), - NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_msec_slot, - NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_core_srv_conf_t, smtp_greeting_delay), - NULL }, - - { ngx_string("so_keepalive"), - NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, - ngx_conf_set_flag_slot, - NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_core_srv_conf_t, so_keepalive), - NULL }, - - { ngx_string("timeout"), - NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_msec_slot, - NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_core_srv_conf_t, timeout), - NULL }, - - { ngx_string("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), + offsetof(ngx_mail_imap_srv_conf_t, client_buffer_size), NULL }, { ngx_string("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_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, + ngx_mail_capabilities, NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_core_srv_conf_t, server_name), + offsetof(ngx_mail_imap_srv_conf_t, capabilities), NULL }, - { ngx_string("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("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("imap_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, imap_auth_methods), - &ngx_imap_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 }, + offsetof(ngx_mail_imap_srv_conf_t, auth_methods), + &ngx_mail_imap_auth_methods }, ngx_null_command }; -static ngx_mail_module_t ngx_mail_core_module_ctx = { - ngx_mail_core_create_main_conf, /* create main configuration */ +static ngx_mail_module_t ngx_mail_imap_module_ctx = { + &ngx_mail_imap_protocol, /* protocol */ + + NULL, /* create main configuration */ NULL, /* init main configuration */ - ngx_mail_core_create_srv_conf, /* create server configuration */ - ngx_mail_core_merge_srv_conf /* merge server configuration */ + ngx_mail_imap_create_srv_conf, /* create server configuration */ + ngx_mail_imap_merge_srv_conf /* merge server configuration */ }; -ngx_module_t ngx_mail_core_module = { +ngx_module_t ngx_mail_imap_module = { NGX_MODULE_V1, - &ngx_mail_core_module_ctx, /* module context */ - ngx_mail_core_commands, /* module directives */ + &ngx_mail_imap_module_ctx, /* module context */ + ngx_mail_imap_commands, /* module directives */ NGX_MAIL_MODULE, /* module type */ NULL, /* init master */ NULL, /* init module */ @@ -246,258 +109,56 @@ ngx_module_t ngx_mail_core_module = { static void * -ngx_mail_core_create_main_conf(ngx_conf_t *cf) +ngx_mail_imap_create_srv_conf(ngx_conf_t *cf) { - ngx_mail_core_main_conf_t *cmcf; - - 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_mail_core_srv_conf_t *)) - != NGX_OK) - { - return NGX_CONF_ERROR; - } + ngx_mail_imap_srv_conf_t *iscf; - if (ngx_array_init(&cmcf->listen, cf->pool, 4, sizeof(ngx_mail_listen_t)) - != NGX_OK) - { - return NGX_CONF_ERROR; - } - - return cmcf; -} - - -static void * -ngx_mail_core_create_srv_conf(ngx_conf_t *cf) -{ - ngx_mail_core_srv_conf_t *cscf; - - cscf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_core_srv_conf_t)); - if (cscf == NULL) { + iscf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_imap_srv_conf_t)); + if (iscf == NULL) { return NULL; } - cscf->imap_client_buffer_size = NGX_CONF_UNSET_SIZE; - cscf->smtp_client_buffer_size = NGX_CONF_UNSET_SIZE; - cscf->protocol = NGX_CONF_UNSET_UINT; - cscf->timeout = NGX_CONF_UNSET_MSEC; - cscf->smtp_greeting_delay = NGX_CONF_UNSET_MSEC; - cscf->so_keepalive = NGX_CONF_UNSET; + iscf->client_buffer_size = NGX_CONF_UNSET_SIZE; - if (ngx_array_init(&cscf->pop3_capabilities, cf->pool, 4, sizeof(ngx_str_t)) - != NGX_OK) - { - return NULL; - } - - if (ngx_array_init(&cscf->imap_capabilities, cf->pool, 4, sizeof(ngx_str_t)) - != NGX_OK) - { - return NULL; - } - - if (ngx_array_init(&cscf->smtp_capabilities, cf->pool, 4, sizeof(ngx_str_t)) + if (ngx_array_init(&iscf->capabilities, cf->pool, 4, sizeof(ngx_str_t)) != NGX_OK) { return NULL; } - return cscf; + return iscf; } static char * -ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) +ngx_mail_imap_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) { - ngx_mail_core_srv_conf_t *prev = parent; - ngx_mail_core_srv_conf_t *conf = child; + ngx_mail_imap_srv_conf_t *prev = parent; + ngx_mail_imap_srv_conf_t *conf = child; u_char *p, *auth; - size_t size, stls_only_size; + size_t size; ngx_str_t *c, *d; 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_size_value(conf->smtp_client_buffer_size, - prev->smtp_client_buffer_size, + ngx_conf_merge_size_value(conf->client_buffer_size, + prev->client_buffer_size, (size_t) ngx_pagesize); - ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 60000); - ngx_conf_merge_msec_value(conf->smtp_greeting_delay, - prev->smtp_greeting_delay, 0); - - ngx_conf_merge_uint_value(conf->protocol, prev->protocol, - NGX_MAIL_IMAP_PROTOCOL); - ngx_conf_merge_value(conf->so_keepalive, prev->so_keepalive, 0); - - 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->imap_auth_methods, - prev->imap_auth_methods, + ngx_conf_merge_bitmask_value(conf->auth_methods, + prev->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, ""); - - if (conf->server_name.len == 0) { - conf->server_name.data = ngx_palloc(cf->pool, NGX_MAXHOSTNAMELEN); - if (conf->server_name.data == NULL) { - return NGX_CONF_ERROR; - } - - if (gethostname((char *) conf->server_name.data, NGX_MAXHOSTNAMELEN) - == -1) - { - ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno, - "gethostname() failed"); - return NGX_CONF_ERROR; - } - - conf->server_name.len = ngx_strlen(conf->server_name.data); - } - - - if (conf->pop3_capabilities.nelts == 0) { - conf->pop3_capabilities = prev->pop3_capabilities; - } - - if (conf->pop3_capabilities.nelts == 0) { - - for (d = ngx_pop3_default_capabilities; d->len; d++) { - c = ngx_array_push(&conf->pop3_capabilities); - if (c == NULL) { - return NGX_CONF_ERROR; - } - - *c = *d; - } - } - - 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->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) { - size += sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1; - - } else { - size += sizeof("SASL LOGIN PLAIN" CRLF) - 1; - } - - p = ngx_palloc(cf->pool, size); - if (p == NULL) { - return NGX_CONF_ERROR; + if (conf->capabilities.nelts == 0) { + conf->capabilities = prev->capabilities; } - conf->pop3_capability.len = size; - conf->pop3_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++) { - p = ngx_cpymem(p, c[i].data, c[i].len); - *p++ = CR; *p++ = LF; - } - - 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); - - } else { - p = ngx_cpymem(p, "SASL LOGIN PLAIN" CRLF, - sizeof("SASL LOGIN PLAIN" CRLF) - 1); - } - - *p++ = '.'; *p++ = CR; *p = LF; - - - size += sizeof("STLS" CRLF) - 1; - - p = ngx_palloc(cf->pool, size); - if (p == NULL) { - return NGX_CONF_ERROR; - } - - conf->pop3_starttls_capability.len = size; - conf->pop3_starttls_capability.data = p; - - p = ngx_cpymem(p, conf->pop3_capability.data, - conf->pop3_capability.len - (sizeof("." CRLF) - 1)); - - p = ngx_cpymem(p, "STLS" CRLF, sizeof("STLS" CRLF) - 1); - *p++ = '.'; *p++ = CR; *p = LF; - + if (conf->capabilities.nelts == 0) { - if (conf->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) { - conf->pop3_auth_capability = ngx_pop3_auth_cram_md5_capability; - - } else { - conf->pop3_auth_capability = ngx_pop3_auth_plain_capability; - } - - - 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; - } - - if (conf->imap_capabilities.nelts == 0) { - - for (d = ngx_imap_default_capabilities; d->len; d++) { - c = ngx_array_push(&conf->imap_capabilities); + for (d = ngx_mail_imap_default_capabilities; d->len; d++) { + c = ngx_array_push(&conf->capabilities); if (c == NULL) { return NGX_CONF_ERROR; } @@ -508,8 +169,8 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t size = sizeof("* CAPABILITY" CRLF) - 1; - c = conf->imap_capabilities.elts; - for (i = 0; i < conf->imap_capabilities.nelts; i++) { + c = conf->capabilities.elts; + for (i = 0; i < conf->capabilities.nelts; i++) { size += 1 + c[i].len; } @@ -517,8 +178,8 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; m <<= 1, i++) { - if (m & conf->imap_auth_methods) { - size += 1 + ngx_imap_auth_methods_names[i].len; + if (m & conf->auth_methods) { + size += 1 + ngx_mail_imap_auth_methods_names[i].len; } } @@ -527,12 +188,12 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t return NGX_CONF_ERROR; } - conf->imap_capability.len = size; - conf->imap_capability.data = p; + conf->capability.len = size; + conf->capability.data = p; p = ngx_cpymem(p, "* CAPABILITY", sizeof("* CAPABILITY") - 1); - for (i = 0; i < conf->imap_capabilities.nelts; i++) { + for (i = 0; i < conf->capabilities.nelts; i++) { *p++ = ' '; p = ngx_cpymem(p, c[i].data, c[i].len); } @@ -543,10 +204,10 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; m <<= 1, i++) { - if (m & conf->imap_auth_methods) { + if (m & conf->auth_methods) { *p++ = ' '; - p = ngx_cpymem(p, ngx_imap_auth_methods_names[i].data, - ngx_imap_auth_methods_names[i].len); + p = ngx_cpymem(p, ngx_mail_imap_auth_methods_names[i].data, + ngx_mail_imap_auth_methods_names[i].len); } } @@ -560,16 +221,16 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t return NGX_CONF_ERROR; } - conf->imap_starttls_capability.len = size; - conf->imap_starttls_capability.data = p; + conf->starttls_capability.len = size; + conf->starttls_capability.data = p; - p = ngx_cpymem(p, conf->imap_capability.data, - conf->imap_capability.len - (sizeof(CRLF) - 1)); + p = ngx_cpymem(p, conf->capability.data, + conf->capability.len - (sizeof(CRLF) - 1)); p = ngx_cpymem(p, " STARTTLS", sizeof(" STARTTLS") - 1); *p++ = CR; *p = LF; - size = (auth - conf->imap_capability.data) + sizeof(CRLF) - 1 + size = (auth - conf->capability.data) + sizeof(CRLF) - 1 + sizeof(" STARTTLS LOGINDISABLED") - 1; p = ngx_palloc(cf->pool, size); @@ -577,308 +238,14 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t return NGX_CONF_ERROR; } - conf->imap_starttls_only_capability.len = size; - conf->imap_starttls_only_capability.data = p; + conf->starttls_only_capability.len = size; + conf->starttls_only_capability.data = p; - p = ngx_cpymem(p, conf->imap_capability.data, - auth - conf->imap_capability.data); + p = ngx_cpymem(p, conf->capability.data, + auth - conf->capability.data); p = ngx_cpymem(p, " STARTTLS LOGINDISABLED", sizeof(" STARTTLS LOGINDISABLED") - 1); *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; - } - - auth = p; - - *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; - - size += sizeof("250 STARTTLS" CRLF) - 1; - - p = ngx_palloc(cf->pool, size); - if (p == NULL) { - return NGX_CONF_ERROR; - } - - conf->smtp_starttls_capability.len = size; - conf->smtp_starttls_capability.data = p; - - p = ngx_cpymem(p, conf->smtp_capability.data, - conf->smtp_capability.len); - - p = ngx_cpymem(p, "250 STARTTLS" CRLF, sizeof("250 STARTTLS" CRLF) - 1); - *p++ = CR; *p = LF; - - p = conf->smtp_starttls_capability.data - + (auth - conf->smtp_capability.data) + 3; - *p = '-'; - - size = (auth - conf->smtp_capability.data) - + sizeof("250 STARTTLS" CRLF) - 1; - - p = ngx_palloc(cf->pool, size); - if (p == NULL) { - return NGX_CONF_ERROR; - } - - conf->smtp_starttls_only_capability.len = size; - conf->smtp_starttls_only_capability.data = p; - - p = ngx_cpymem(p, conf->smtp_capability.data, - auth - conf->smtp_capability.data); - - ngx_memcpy(p, "250 STARTTLS" CRLF, sizeof("250 STARTTLS" CRLF) - 1); - return NGX_CONF_OK; } - - -static char * -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_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_mail_conf_ctx_t)); - if (ctx == NULL) { - return NGX_CONF_ERROR; - } - - 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_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_MAIL_MODULE) { - continue; - } - - module = ngx_modules[m]->ctx; - - if (module->create_srv_conf) { - mconf = module->create_srv_conf(cf); - if (mconf == NULL) { - return NGX_CONF_ERROR; - } - - ctx->srv_conf[ngx_modules[m]->ctx_index] = mconf; - } - } - - /* the server configuration context */ - - cscf = ctx->srv_conf[ngx_mail_core_module.ctx_index]; - cscf->ctx = ctx; - - cmcf = ctx->main_conf[ngx_mail_core_module.ctx_index]; - - cscfp = ngx_array_push(&cmcf->servers); - if (cscfp == NULL) { - return NGX_CONF_ERROR; - } - - *cscfp = cscf; - - - /* parse inside server{} */ - - pcf = *cf; - cf->ctx = ctx; - cf->cmd_type = NGX_MAIL_SRV_CONF; - - rv = ngx_conf_parse(cf, NULL); - - *cf = pcf; - - return rv; -} - - -/* AF_INET only */ - -static char * -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_mail_listen_t *imls; - ngx_mail_core_main_conf_t *cmcf; - - value = cf->args->elts; - - ngx_memzero(&u, sizeof(ngx_url_t)); - - u.url = value[1]; - u.listen = 1; - - if (ngx_parse_url(cf, &u) != NGX_OK) { - if (u.err) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "%s in \"%V\" of the \"listen\" directive", - u.err, &u.url); - } - - return NGX_CONF_ERROR; - } - - cmcf = ngx_mail_conf_get_module_main_conf(cf, ngx_mail_core_module); - - imls = cmcf->listen.elts; - - for (i = 0; i < cmcf->listen.nelts; i++) { - - if (imls[i].addr != u.addr.in_addr || imls[i].port != u.port) { - continue; - } - - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "duplicate \"%V\" address and port pair", &u.url); - return NGX_CONF_ERROR; - } - - imls = ngx_array_push(&cmcf->listen); - if (imls == NULL) { - return NGX_CONF_ERROR; - } - - ngx_memzero(imls, sizeof(ngx_mail_listen_t)); - - imls->addr = u.addr.in_addr; - imls->port = u.port; - imls->family = AF_INET; - imls->ctx = cf->ctx; - - if (cf->args->nelts == 2) { - return NGX_CONF_OK; - } - - if (ngx_strcmp(value[2].data, "bind") == 0) { - imls->bind = 1; - return NGX_CONF_OK; - } - - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "the invalid \"%V\" parameter", &value[2]); - return NGX_CONF_ERROR; -} - - -static char * -ngx_mail_core_capability(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - char *p = conf; - - ngx_str_t *c, *value; - ngx_uint_t i; - ngx_array_t *a; - - a = (ngx_array_t *) (p + cmd->offset); - - value = cf->args->elts; - - for (i = 1; i < cf->args->nelts; i++) { - c = ngx_array_push(a); - if (c == NULL) { - return NGX_CONF_ERROR; - } - - *c = value[i]; - } - - return NGX_CONF_OK; -} diff --git a/src/mail/ngx_mail_imap_module.h b/src/mail/ngx_mail_imap_module.h new file mode 100644 --- /dev/null +++ b/src/mail/ngx_mail_imap_module.h @@ -0,0 +1,38 @@ + +/* + * Copyright (C) Igor Sysoev + */ + + +#ifndef _NGX_MAIL_IMAP_MODULE_H_INCLUDED_ +#define _NGX_MAIL_IMAP_MODULE_H_INCLUDED_ + + +#include +#include +#include + + +typedef struct { + size_t client_buffer_size; + + ngx_str_t capability; + ngx_str_t starttls_capability; + ngx_str_t starttls_only_capability; + + ngx_uint_t auth_methods; + + ngx_array_t capabilities; +} ngx_mail_imap_srv_conf_t; + + +void ngx_mail_imap_init_session(ngx_mail_session_t *s, ngx_connection_t *c); +void ngx_mail_imap_init_protocol(ngx_event_t *rev); +void ngx_mail_imap_auth_state(ngx_event_t *rev); +ngx_int_t ngx_mail_imap_parse_command(ngx_mail_session_t *s); + + +extern ngx_module_t ngx_mail_imap_module; + + +#endif /* _NGX_MAIL_IMAP_MODULE_H_INCLUDED_ */ diff --git a/src/mail/ngx_mail_pop3_handler.c b/src/mail/ngx_mail_pop3_handler.c --- a/src/mail/ngx_mail_pop3_handler.c +++ b/src/mail/ngx_mail_pop3_handler.c @@ -8,6 +8,7 @@ #include #include #include +#include static ngx_int_t ngx_mail_pop3_user(ngx_mail_session_t *s, ngx_connection_t *c); @@ -32,10 +33,12 @@ ngx_mail_pop3_init_session(ngx_mail_sess { u_char *p; ngx_mail_core_srv_conf_t *cscf; + ngx_mail_pop3_srv_conf_t *pscf; + pscf = ngx_mail_get_module_srv_conf(s, ngx_mail_pop3_module); cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); - if (cscf->pop3_auth_methods + if (pscf->auth_methods & (NGX_MAIL_AUTH_APOP_ENABLED|NGX_MAIL_AUTH_CRAM_MD5_ENABLED)) { if (ngx_mail_salt(s, c, cscf) != NGX_OK) { @@ -340,12 +343,12 @@ ngx_mail_pop3_pass(ngx_mail_session_t *s static ngx_int_t ngx_mail_pop3_capa(ngx_mail_session_t *s, ngx_connection_t *c, ngx_int_t stls) { - ngx_mail_core_srv_conf_t *cscf; + ngx_mail_pop3_srv_conf_t *pscf; #if (NGX_MAIL_SSL) ngx_mail_ssl_conf_t *sslcf; #endif - cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); + pscf = ngx_mail_get_module_srv_conf(s, ngx_mail_pop3_module); #if (NGX_MAIL_SSL) @@ -353,19 +356,19 @@ ngx_mail_pop3_capa(ngx_mail_session_t *s sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module); if (sslcf->starttls == NGX_MAIL_STARTTLS_ON) { - s->out = cscf->pop3_starttls_capability; + s->out = pscf->starttls_capability; return NGX_OK; } if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) { - s->out = cscf->pop3_starttls_only_capability; + s->out = pscf->starttls_only_capability; return NGX_OK; } } #endif - s->out = cscf->pop3_capability; + s->out = pscf->capability; return NGX_OK; } @@ -394,7 +397,7 @@ static ngx_int_t ngx_mail_pop3_apop(ngx_mail_session_t *s, ngx_connection_t *c) { ngx_str_t *arg; - ngx_mail_core_srv_conf_t *cscf; + ngx_mail_pop3_srv_conf_t *pscf; #if (NGX_MAIL_SSL) if (ngx_mail_starttls_only(s, c)) { @@ -406,9 +409,9 @@ ngx_mail_pop3_apop(ngx_mail_session_t *s return NGX_MAIL_PARSE_INVALID_COMMAND; } - cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); + pscf = ngx_mail_get_module_srv_conf(s, ngx_mail_pop3_module); - if (!(cscf->pop3_auth_methods & NGX_MAIL_AUTH_APOP_ENABLED)) { + if (!(pscf->auth_methods & NGX_MAIL_AUTH_APOP_ENABLED)) { return NGX_MAIL_PARSE_INVALID_COMMAND; } @@ -443,7 +446,7 @@ static ngx_int_t ngx_mail_pop3_auth(ngx_mail_session_t *s, ngx_connection_t *c) { ngx_int_t rc; - ngx_mail_core_srv_conf_t *cscf; + ngx_mail_pop3_srv_conf_t *pscf; #if (NGX_MAIL_SSL) if (ngx_mail_starttls_only(s, c)) { @@ -451,10 +454,10 @@ ngx_mail_pop3_auth(ngx_mail_session_t *s } #endif - cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); + pscf = ngx_mail_get_module_srv_conf(s, ngx_mail_pop3_module); if (s->args.nelts == 0) { - s->out = cscf->pop3_auth_capability; + s->out = pscf->auth_capability; s->state = 0; return NGX_OK; @@ -482,7 +485,7 @@ ngx_mail_pop3_auth(ngx_mail_session_t *s case NGX_MAIL_AUTH_CRAM_MD5: - if (!(cscf->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED)) { + if (!(pscf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED)) { return NGX_MAIL_PARSE_INVALID_COMMAND; } diff --git a/src/mail/ngx_mail_core_module.c b/src/mail/ngx_mail_pop3_module.c copy from src/mail/ngx_mail_core_module.c copy to src/mail/ngx_mail_pop3_module.c --- a/src/mail/ngx_mail_core_module.c +++ b/src/mail/ngx_mail_pop3_module.c @@ -8,29 +8,15 @@ #include #include #include +#include -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, +static void *ngx_mail_pop3_create_srv_conf(ngx_conf_t *cf); +static char *ngx_mail_pop3_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child); -static char *ngx_mail_core_server(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -static char *ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -static char *ngx_mail_core_capability(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -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 } -}; - - -static ngx_str_t ngx_pop3_default_capabilities[] = { +static ngx_str_t ngx_mail_pop3_default_capabilities[] = { ngx_string("TOP"), ngx_string("USER"), ngx_string("UIDL"), @@ -38,15 +24,7 @@ static ngx_str_t ngx_pop3_default_capab }; -static ngx_str_t ngx_imap_default_capabilities[] = { - ngx_string("IMAP4"), - ngx_string("IMAP4rev1"), - ngx_string("UIDPLUS"), - ngx_null_string -}; - - -static ngx_conf_bitmask_t ngx_pop3_auth_methods[] = { +static ngx_conf_bitmask_t ngx_mail_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 }, @@ -54,46 +32,14 @@ static ngx_conf_bitmask_t ngx_pop3_auth }; -static ngx_conf_bitmask_t ngx_imap_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_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_imap_auth_methods_names[] = { - ngx_string("AUTH=PLAIN"), - ngx_string("AUTH=LOGIN"), - ngx_null_string, /* APOP */ - ngx_string("AUTH=CRAM-MD5") -}; - - -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 = +static ngx_str_t ngx_mail_pop3_auth_plain_capability = ngx_string("+OK methods supported:" CRLF "LOGIN" CRLF "PLAIN" CRLF "." CRLF); -static ngx_str_t ngx_pop3_auth_cram_md5_capability = +static ngx_str_t ngx_mail_pop3_auth_cram_md5_capability = ngx_string("+OK methods supported:" CRLF "LOGIN" CRLF "PLAIN" CRLF @@ -101,138 +47,55 @@ static ngx_str_t ngx_pop3_auth_cram_md5 "." CRLF); - -static ngx_command_t ngx_mail_core_commands[] = { - - { ngx_string("server"), - NGX_MAIL_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, - ngx_mail_core_server, - 0, - 0, - NULL }, - - { ngx_string("listen"), - NGX_MAIL_SRV_CONF|NGX_CONF_TAKE12, - ngx_mail_core_listen, - 0, - 0, - NULL }, - - { ngx_string("protocol"), - NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_enum_slot, - NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_core_srv_conf_t, protocol), - &ngx_mail_core_procotol }, +static ngx_mail_protocol_t ngx_mail_pop3_protocol = { + ngx_string("pop3"), + { 110, 995, 0, 0 }, + NGX_MAIL_POP3_PROTOCOL, - { ngx_string("imap_client_buffer"), - NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_size_slot, - NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_core_srv_conf_t, imap_client_buffer_size), - NULL }, - - { ngx_string("smtp_client_buffer"), - NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_size_slot, - NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_core_srv_conf_t, smtp_client_buffer_size), - NULL }, + ngx_mail_pop3_init_session, + ngx_mail_pop3_init_protocol, + ngx_mail_pop3_parse_command, + ngx_mail_pop3_auth_state, - { ngx_string("smtp_greeting_delay"), - NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_msec_slot, - NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_core_srv_conf_t, smtp_greeting_delay), - NULL }, + ngx_string("-ERR internal server error" CRLF) +}; - { ngx_string("so_keepalive"), - NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, - ngx_conf_set_flag_slot, - NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_core_srv_conf_t, so_keepalive), - NULL }, - { ngx_string("timeout"), - NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_msec_slot, - NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_core_srv_conf_t, timeout), - NULL }, +static ngx_command_t ngx_mail_pop3_commands[] = { { ngx_string("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_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_capabilities, NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_core_srv_conf_t, smtp_capabilities), + offsetof(ngx_mail_pop3_srv_conf_t, capabilities), NULL }, - { ngx_string("server_name"), - NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, - NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_core_srv_conf_t, server_name), - NULL }, - - { ngx_string("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("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("imap_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, imap_auth_methods), - &ngx_imap_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 }, + offsetof(ngx_mail_pop3_srv_conf_t, auth_methods), + &ngx_mail_pop3_auth_methods }, ngx_null_command }; -static ngx_mail_module_t ngx_mail_core_module_ctx = { - ngx_mail_core_create_main_conf, /* create main configuration */ +static ngx_mail_module_t ngx_mail_pop3_module_ctx = { + &ngx_mail_pop3_protocol, /* protocol */ + + NULL, /* create main configuration */ NULL, /* init main configuration */ - ngx_mail_core_create_srv_conf, /* create server configuration */ - ngx_mail_core_merge_srv_conf /* merge server configuration */ + ngx_mail_pop3_create_srv_conf, /* create server configuration */ + ngx_mail_pop3_merge_srv_conf /* merge server configuration */ }; -ngx_module_t ngx_mail_core_module = { +ngx_module_t ngx_mail_pop3_module = { NGX_MODULE_V1, - &ngx_mail_core_module_ctx, /* module context */ - ngx_mail_core_commands, /* module directives */ + &ngx_mail_pop3_module_ctx, /* module context */ + ngx_mail_pop3_commands, /* module directives */ NGX_MAIL_MODULE, /* module type */ NULL, /* init master */ NULL, /* init module */ @@ -246,142 +109,49 @@ ngx_module_t ngx_mail_core_module = { static void * -ngx_mail_core_create_main_conf(ngx_conf_t *cf) +ngx_mail_pop3_create_srv_conf(ngx_conf_t *cf) { - ngx_mail_core_main_conf_t *cmcf; - - 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_mail_core_srv_conf_t *)) - != NGX_OK) - { - return NGX_CONF_ERROR; - } + ngx_mail_pop3_srv_conf_t *pscf; - if (ngx_array_init(&cmcf->listen, cf->pool, 4, sizeof(ngx_mail_listen_t)) - != NGX_OK) - { - return NGX_CONF_ERROR; - } - - return cmcf; -} - - -static void * -ngx_mail_core_create_srv_conf(ngx_conf_t *cf) -{ - ngx_mail_core_srv_conf_t *cscf; - - cscf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_core_srv_conf_t)); - if (cscf == NULL) { + pscf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_pop3_srv_conf_t)); + if (pscf == NULL) { return NULL; } - cscf->imap_client_buffer_size = NGX_CONF_UNSET_SIZE; - cscf->smtp_client_buffer_size = NGX_CONF_UNSET_SIZE; - cscf->protocol = NGX_CONF_UNSET_UINT; - cscf->timeout = NGX_CONF_UNSET_MSEC; - cscf->smtp_greeting_delay = NGX_CONF_UNSET_MSEC; - cscf->so_keepalive = NGX_CONF_UNSET; - - if (ngx_array_init(&cscf->pop3_capabilities, cf->pool, 4, sizeof(ngx_str_t)) - != NGX_OK) - { - return NULL; - } - - if (ngx_array_init(&cscf->imap_capabilities, cf->pool, 4, sizeof(ngx_str_t)) - != NGX_OK) - { - return NULL; - } - - if (ngx_array_init(&cscf->smtp_capabilities, cf->pool, 4, sizeof(ngx_str_t)) + if (ngx_array_init(&pscf->capabilities, cf->pool, 4, sizeof(ngx_str_t)) != NGX_OK) { return NULL; } - return cscf; + return pscf; } static char * -ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) +ngx_mail_pop3_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) { - ngx_mail_core_srv_conf_t *prev = parent; - ngx_mail_core_srv_conf_t *conf = child; + ngx_mail_pop3_srv_conf_t *prev = parent; + ngx_mail_pop3_srv_conf_t *conf = child; - u_char *p, *auth; + u_char *p; size_t size, stls_only_size; ngx_str_t *c, *d; - 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_size_value(conf->smtp_client_buffer_size, - prev->smtp_client_buffer_size, - (size_t) ngx_pagesize); - - ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 60000); - ngx_conf_merge_msec_value(conf->smtp_greeting_delay, - prev->smtp_greeting_delay, 0); - - ngx_conf_merge_uint_value(conf->protocol, prev->protocol, - NGX_MAIL_IMAP_PROTOCOL); - ngx_conf_merge_value(conf->so_keepalive, prev->so_keepalive, 0); - - ngx_conf_merge_bitmask_value(conf->pop3_auth_methods, - prev->pop3_auth_methods, - (NGX_CONF_BITMASK_SET - |NGX_MAIL_AUTH_PLAIN_ENABLED)); + ngx_uint_t i; - ngx_conf_merge_bitmask_value(conf->imap_auth_methods, - prev->imap_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, ""); + ngx_conf_merge_bitmask_value(conf->auth_methods, + prev->auth_methods, + (NGX_CONF_BITMASK_SET + |NGX_MAIL_AUTH_PLAIN_ENABLED)); - if (conf->server_name.len == 0) { - conf->server_name.data = ngx_palloc(cf->pool, NGX_MAXHOSTNAMELEN); - if (conf->server_name.data == NULL) { - return NGX_CONF_ERROR; - } - - if (gethostname((char *) conf->server_name.data, NGX_MAXHOSTNAMELEN) - == -1) - { - ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno, - "gethostname() failed"); - return NGX_CONF_ERROR; - } - - conf->server_name.len = ngx_strlen(conf->server_name.data); + if (conf->capabilities.nelts == 0) { + conf->capabilities = prev->capabilities; } - - if (conf->pop3_capabilities.nelts == 0) { - conf->pop3_capabilities = prev->pop3_capabilities; - } + if (conf->capabilities.nelts == 0) { - if (conf->pop3_capabilities.nelts == 0) { - - for (d = ngx_pop3_default_capabilities; d->len; d++) { - c = ngx_array_push(&conf->pop3_capabilities); + for (d = ngx_mail_pop3_default_capabilities; d->len; d++) { + c = ngx_array_push(&conf->capabilities); if (c == NULL) { return NGX_CONF_ERROR; } @@ -395,8 +165,8 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t stls_only_size = size + sizeof("STLS" CRLF) - 1; - c = conf->pop3_capabilities.elts; - for (i = 0; i < conf->pop3_capabilities.nelts; i++) { + c = conf->capabilities.elts; + for (i = 0; i < conf->capabilities.nelts; i++) { size += c[i].len + sizeof(CRLF) - 1; if (ngx_strcasecmp(c[i].data, (u_char *) "USER") == 0) { @@ -406,7 +176,7 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t stls_only_size += c[i].len + sizeof(CRLF) - 1; } - if (conf->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) { + if (conf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) { size += sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1; } else { @@ -418,18 +188,18 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t return NGX_CONF_ERROR; } - conf->pop3_capability.len = size; - conf->pop3_capability.data = p; + conf->capability.len = size; + conf->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++) { + for (i = 0; i < conf->capabilities.nelts; i++) { p = ngx_cpymem(p, c[i].data, c[i].len); *p++ = CR; *p++ = LF; } - if (conf->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) { + if (conf->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); @@ -448,21 +218,21 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t return NGX_CONF_ERROR; } - conf->pop3_starttls_capability.len = size; - conf->pop3_starttls_capability.data = p; + conf->starttls_capability.len = size; + conf->starttls_capability.data = p; - p = ngx_cpymem(p, conf->pop3_capability.data, - conf->pop3_capability.len - (sizeof("." CRLF) - 1)); + p = ngx_cpymem(p, conf->capability.data, + conf->capability.len - (sizeof("." CRLF) - 1)); p = ngx_cpymem(p, "STLS" CRLF, sizeof("STLS" CRLF) - 1); *p++ = '.'; *p++ = CR; *p = LF; - if (conf->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) { - conf->pop3_auth_capability = ngx_pop3_auth_cram_md5_capability; + if (conf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) { + conf->auth_capability = ngx_mail_pop3_auth_cram_md5_capability; } else { - conf->pop3_auth_capability = ngx_pop3_auth_plain_capability; + conf->auth_capability = ngx_mail_pop3_auth_plain_capability; } @@ -471,13 +241,13 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t return NGX_CONF_ERROR; } - conf->pop3_starttls_only_capability.len = stls_only_size; - conf->pop3_starttls_only_capability.data = p; + conf->starttls_only_capability.len = stls_only_size; + conf->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++) { + for (i = 0; i < conf->capabilities.nelts; i++) { if (ngx_strcasecmp(c[i].data, (u_char *) "USER") == 0) { continue; } @@ -489,396 +259,5 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t 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; - } - - if (conf->imap_capabilities.nelts == 0) { - - for (d = ngx_imap_default_capabilities; d->len; d++) { - c = ngx_array_push(&conf->imap_capabilities); - if (c == NULL) { - return NGX_CONF_ERROR; - } - - *c = *d; - } - } - - size = sizeof("* CAPABILITY" CRLF) - 1; - - c = conf->imap_capabilities.elts; - for (i = 0; i < conf->imap_capabilities.nelts; i++) { - size += 1 + c[i].len; - } - - for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; - m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; - m <<= 1, i++) - { - if (m & conf->imap_auth_methods) { - size += 1 + ngx_imap_auth_methods_names[i].len; - } - } - - p = ngx_palloc(cf->pool, size); - if (p == NULL) { - return NGX_CONF_ERROR; - } - - conf->imap_capability.len = size; - conf->imap_capability.data = p; - - p = ngx_cpymem(p, "* CAPABILITY", sizeof("* CAPABILITY") - 1); - - for (i = 0; i < conf->imap_capabilities.nelts; i++) { - *p++ = ' '; - p = ngx_cpymem(p, c[i].data, c[i].len); - } - - auth = p; - - for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; - m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; - m <<= 1, i++) - { - if (m & conf->imap_auth_methods) { - *p++ = ' '; - p = ngx_cpymem(p, ngx_imap_auth_methods_names[i].data, - ngx_imap_auth_methods_names[i].len); - } - } - - *p++ = CR; *p = LF; - - - size += sizeof(" STARTTLS") - 1; - - p = ngx_palloc(cf->pool, size); - if (p == NULL) { - return NGX_CONF_ERROR; - } - - conf->imap_starttls_capability.len = size; - conf->imap_starttls_capability.data = p; - - p = ngx_cpymem(p, conf->imap_capability.data, - conf->imap_capability.len - (sizeof(CRLF) - 1)); - p = ngx_cpymem(p, " STARTTLS", sizeof(" STARTTLS") - 1); - *p++ = CR; *p = LF; - - - size = (auth - conf->imap_capability.data) + sizeof(CRLF) - 1 - + sizeof(" STARTTLS LOGINDISABLED") - 1; - - p = ngx_palloc(cf->pool, size); - if (p == NULL) { - return NGX_CONF_ERROR; - } - - conf->imap_starttls_only_capability.len = size; - conf->imap_starttls_only_capability.data = p; - - p = ngx_cpymem(p, conf->imap_capability.data, - auth - conf->imap_capability.data); - p = ngx_cpymem(p, " STARTTLS LOGINDISABLED", - sizeof(" STARTTLS LOGINDISABLED") - 1); - *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; - } - - auth = p; - - *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; - - size += sizeof("250 STARTTLS" CRLF) - 1; - - p = ngx_palloc(cf->pool, size); - if (p == NULL) { - return NGX_CONF_ERROR; - } - - conf->smtp_starttls_capability.len = size; - conf->smtp_starttls_capability.data = p; - - p = ngx_cpymem(p, conf->smtp_capability.data, - conf->smtp_capability.len); - - p = ngx_cpymem(p, "250 STARTTLS" CRLF, sizeof("250 STARTTLS" CRLF) - 1); - *p++ = CR; *p = LF; - - p = conf->smtp_starttls_capability.data - + (auth - conf->smtp_capability.data) + 3; - *p = '-'; - - size = (auth - conf->smtp_capability.data) - + sizeof("250 STARTTLS" CRLF) - 1; - - p = ngx_palloc(cf->pool, size); - if (p == NULL) { - return NGX_CONF_ERROR; - } - - conf->smtp_starttls_only_capability.len = size; - conf->smtp_starttls_only_capability.data = p; - - p = ngx_cpymem(p, conf->smtp_capability.data, - auth - conf->smtp_capability.data); - - ngx_memcpy(p, "250 STARTTLS" CRLF, sizeof("250 STARTTLS" CRLF) - 1); - return NGX_CONF_OK; } - - -static char * -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_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_mail_conf_ctx_t)); - if (ctx == NULL) { - return NGX_CONF_ERROR; - } - - 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_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_MAIL_MODULE) { - continue; - } - - module = ngx_modules[m]->ctx; - - if (module->create_srv_conf) { - mconf = module->create_srv_conf(cf); - if (mconf == NULL) { - return NGX_CONF_ERROR; - } - - ctx->srv_conf[ngx_modules[m]->ctx_index] = mconf; - } - } - - /* the server configuration context */ - - cscf = ctx->srv_conf[ngx_mail_core_module.ctx_index]; - cscf->ctx = ctx; - - cmcf = ctx->main_conf[ngx_mail_core_module.ctx_index]; - - cscfp = ngx_array_push(&cmcf->servers); - if (cscfp == NULL) { - return NGX_CONF_ERROR; - } - - *cscfp = cscf; - - - /* parse inside server{} */ - - pcf = *cf; - cf->ctx = ctx; - cf->cmd_type = NGX_MAIL_SRV_CONF; - - rv = ngx_conf_parse(cf, NULL); - - *cf = pcf; - - return rv; -} - - -/* AF_INET only */ - -static char * -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_mail_listen_t *imls; - ngx_mail_core_main_conf_t *cmcf; - - value = cf->args->elts; - - ngx_memzero(&u, sizeof(ngx_url_t)); - - u.url = value[1]; - u.listen = 1; - - if (ngx_parse_url(cf, &u) != NGX_OK) { - if (u.err) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "%s in \"%V\" of the \"listen\" directive", - u.err, &u.url); - } - - return NGX_CONF_ERROR; - } - - cmcf = ngx_mail_conf_get_module_main_conf(cf, ngx_mail_core_module); - - imls = cmcf->listen.elts; - - for (i = 0; i < cmcf->listen.nelts; i++) { - - if (imls[i].addr != u.addr.in_addr || imls[i].port != u.port) { - continue; - } - - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "duplicate \"%V\" address and port pair", &u.url); - return NGX_CONF_ERROR; - } - - imls = ngx_array_push(&cmcf->listen); - if (imls == NULL) { - return NGX_CONF_ERROR; - } - - ngx_memzero(imls, sizeof(ngx_mail_listen_t)); - - imls->addr = u.addr.in_addr; - imls->port = u.port; - imls->family = AF_INET; - imls->ctx = cf->ctx; - - if (cf->args->nelts == 2) { - return NGX_CONF_OK; - } - - if (ngx_strcmp(value[2].data, "bind") == 0) { - imls->bind = 1; - return NGX_CONF_OK; - } - - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "the invalid \"%V\" parameter", &value[2]); - return NGX_CONF_ERROR; -} - - -static char * -ngx_mail_core_capability(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - char *p = conf; - - ngx_str_t *c, *value; - ngx_uint_t i; - ngx_array_t *a; - - a = (ngx_array_t *) (p + cmd->offset); - - value = cf->args->elts; - - for (i = 1; i < cf->args->nelts; i++) { - c = ngx_array_push(a); - if (c == NULL) { - return NGX_CONF_ERROR; - } - - *c = value[i]; - } - - return NGX_CONF_OK; -} diff --git a/src/mail/ngx_mail_pop3_module.h b/src/mail/ngx_mail_pop3_module.h new file mode 100644 --- /dev/null +++ b/src/mail/ngx_mail_pop3_module.h @@ -0,0 +1,37 @@ + +/* + * Copyright (C) Igor Sysoev + */ + + +#ifndef _NGX_MAIL_POP3_MODULE_H_INCLUDED_ +#define _NGX_MAIL_POP3_MODULE_H_INCLUDED_ + + +#include +#include +#include + + +typedef struct { + ngx_str_t capability; + ngx_str_t starttls_capability; + ngx_str_t starttls_only_capability; + ngx_str_t auth_capability; + + ngx_uint_t auth_methods; + + ngx_array_t capabilities; +} ngx_mail_pop3_srv_conf_t; + + +void ngx_mail_pop3_init_session(ngx_mail_session_t *s, ngx_connection_t *c); +void ngx_mail_pop3_init_protocol(ngx_event_t *rev); +void ngx_mail_pop3_auth_state(ngx_event_t *rev); +ngx_int_t ngx_mail_pop3_parse_command(ngx_mail_session_t *s); + + +extern ngx_module_t ngx_mail_pop3_module; + + +#endif /* _NGX_MAIL_POP3_MODULE_H_INCLUDED_ */ diff --git a/src/mail/ngx_mail_proxy_module.c b/src/mail/ngx_mail_proxy_module.c --- a/src/mail/ngx_mail_proxy_module.c +++ b/src/mail/ngx_mail_proxy_module.c @@ -78,6 +78,8 @@ static ngx_command_t ngx_mail_proxy_com static ngx_mail_module_t ngx_mail_proxy_module_ctx = { + NULL, /* protocol */ + NULL, /* create main configuration */ NULL, /* init main configuration */ diff --git a/src/mail/ngx_mail_smtp_handler.c b/src/mail/ngx_mail_smtp_handler.c --- a/src/mail/ngx_mail_smtp_handler.c +++ b/src/mail/ngx_mail_smtp_handler.c @@ -8,6 +8,7 @@ #include #include #include +#include static void ngx_mail_smtp_invalid_pipelining(ngx_event_t *rev); @@ -43,25 +44,26 @@ ngx_mail_smtp_init_session(ngx_mail_sess { ngx_msec_t timeout; ngx_mail_core_srv_conf_t *cscf; + ngx_mail_smtp_srv_conf_t *sscf; cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); + sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module); - timeout = cscf->smtp_greeting_delay ? cscf->smtp_greeting_delay: - cscf->timeout; + timeout = sscf->greeting_delay ? sscf->greeting_delay : cscf->timeout; ngx_add_timer(c->read, timeout); if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) { ngx_mail_close_connection(c); } - if (cscf->smtp_greeting_delay) { + if (sscf->greeting_delay) { c->read->handler = ngx_mail_smtp_invalid_pipelining; return; } c->read->handler = ngx_mail_smtp_init_protocol; - s->out = cscf->smtp_greeting; + s->out = sscf->greeting; ngx_mail_send(c->write); } @@ -73,6 +75,7 @@ ngx_mail_smtp_invalid_pipelining(ngx_eve ngx_connection_t *c; ngx_mail_session_t *s; ngx_mail_core_srv_conf_t *cscf; + ngx_mail_smtp_srv_conf_t *sscf; c = rev->data; s = c->data; @@ -96,7 +99,9 @@ ngx_mail_smtp_invalid_pipelining(ngx_eve return; } - s->out = cscf->smtp_greeting; + sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module); + + s->out = sscf->greeting; } else { @@ -158,16 +163,16 @@ ngx_mail_smtp_init_protocol(ngx_event_t static ngx_int_t ngx_mail_smtp_create_buffer(ngx_mail_session_t *s, ngx_connection_t *c) { - ngx_mail_core_srv_conf_t *cscf; + ngx_mail_smtp_srv_conf_t *sscf; if (ngx_array_init(&s->args, c->pool, 2, sizeof(ngx_str_t)) == NGX_ERROR) { ngx_mail_session_internal_server_error(s); return NGX_ERROR; } - cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); + sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module); - s->buffer = ngx_create_temp_buf(c->pool, cscf->smtp_client_buffer_size); + s->buffer = ngx_create_temp_buf(c->pool, sscf->client_buffer_size); if (s->buffer == NULL) { ngx_mail_session_internal_server_error(s); return NGX_ERROR; @@ -313,13 +318,11 @@ static ngx_int_t ngx_mail_smtp_helo(ngx_mail_session_t *s, ngx_connection_t *c) { ngx_str_t *arg; - ngx_mail_core_srv_conf_t *cscf; + ngx_mail_smtp_srv_conf_t *sscf; #if (NGX_MAIL_SSL) ngx_mail_ssl_conf_t *sslcf; #endif - cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); - if (s->args.nelts != 1) { s->out.len = sizeof(smtp_invalid_argument) - 1; s->out.data = smtp_invalid_argument; @@ -338,8 +341,10 @@ ngx_mail_smtp_helo(ngx_mail_session_t *s ngx_memcpy(s->smtp_helo.data, arg[0].data, arg[0].len); + sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module); + if (s->command == NGX_SMTP_HELO) { - s->out = cscf->smtp_server_name; + s->out = sscf->server_name; } else { s->esmtp = 1; @@ -350,18 +355,18 @@ ngx_mail_smtp_helo(ngx_mail_session_t *s sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module); if (sslcf->starttls == NGX_MAIL_STARTTLS_ON) { - s->out = cscf->smtp_starttls_capability; + s->out = sscf->starttls_capability; return NGX_OK; } if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) { - s->out = cscf->smtp_starttls_only_capability; + s->out = sscf->starttls_only_capability; return NGX_OK; } } #endif - s->out = cscf->smtp_capability; + s->out = sscf->capability; } return NGX_OK; @@ -373,6 +378,7 @@ ngx_mail_smtp_auth(ngx_mail_session_t *s { ngx_int_t rc; ngx_mail_core_srv_conf_t *cscf; + ngx_mail_smtp_srv_conf_t *sscf; #if (NGX_MAIL_SSL) if (ngx_mail_starttls_only(s, c)) { @@ -409,13 +415,15 @@ ngx_mail_smtp_auth(ngx_mail_session_t *s case NGX_MAIL_AUTH_CRAM_MD5: - cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); + sscf = ngx_mail_get_module_srv_conf(s, ngx_mail_smtp_module); - if (!(cscf->smtp_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED)) { + if (!(sscf->auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED)) { return NGX_MAIL_PARSE_INVALID_COMMAND; } if (s->salt.data == NULL) { + cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); + if (ngx_mail_salt(s, c, cscf) != NGX_OK) { return NGX_ERROR; } diff --git a/src/mail/ngx_mail_core_module.c b/src/mail/ngx_mail_smtp_module.c copy from src/mail/ngx_mail_core_module.c copy to src/mail/ngx_mail_smtp_module.c --- a/src/mail/ngx_mail_core_module.c +++ b/src/mail/ngx_mail_smtp_module.c @@ -8,53 +8,15 @@ #include #include #include - - -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_mail_core_server(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -static char *ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); -static char *ngx_mail_core_capability(ngx_conf_t *cf, ngx_command_t *cmd, - void *conf); - - -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 } -}; +#include -static ngx_str_t ngx_pop3_default_capabilities[] = { - ngx_string("TOP"), - ngx_string("USER"), - ngx_string("UIDL"), - ngx_null_string -}; +static void *ngx_mail_smtp_create_srv_conf(ngx_conf_t *cf); +static char *ngx_mail_smtp_merge_srv_conf(ngx_conf_t *cf, void *parent, + void *child); -static ngx_str_t ngx_imap_default_capabilities[] = { - ngx_string("IMAP4"), - ngx_string("IMAP4rev1"), - ngx_string("UIDPLUS"), - ngx_null_string -}; - - -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_imap_auth_methods[] = { +static ngx_conf_bitmask_t ngx_mail_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 }, @@ -62,23 +24,7 @@ static ngx_conf_bitmask_t ngx_imap_auth }; -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_imap_auth_methods_names[] = { - ngx_string("AUTH=PLAIN"), - ngx_string("AUTH=LOGIN"), - ngx_null_string, /* APOP */ - ngx_string("AUTH=CRAM-MD5") -}; - - -static ngx_str_t ngx_smtp_auth_methods_names[] = { +static ngx_str_t ngx_mail_smtp_auth_methods_names[] = { ngx_string("PLAIN"), ngx_string("LOGIN"), ngx_null_string, /* APOP */ @@ -86,153 +32,69 @@ static ngx_str_t ngx_smtp_auth_methods_ }; -static ngx_str_t ngx_pop3_auth_plain_capability = - ngx_string("+OK methods supported:" CRLF - "LOGIN" CRLF - "PLAIN" CRLF - "." CRLF); - +static ngx_mail_protocol_t ngx_mail_smtp_protocol = { + ngx_string("smtp"), + { 25, 465, 587, 0 }, + NGX_MAIL_SMTP_PROTOCOL, -static ngx_str_t ngx_pop3_auth_cram_md5_capability = - ngx_string("+OK methods supported:" CRLF - "LOGIN" CRLF - "PLAIN" CRLF - "CRAM-MD5" CRLF - "." CRLF); + ngx_mail_smtp_init_session, + ngx_mail_smtp_init_protocol, + ngx_mail_smtp_parse_command, + ngx_mail_smtp_auth_state, + ngx_string("451 4.3.2 Internal server error" CRLF) +}; -static ngx_command_t ngx_mail_core_commands[] = { - - { ngx_string("server"), - NGX_MAIL_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, - ngx_mail_core_server, - 0, - 0, - NULL }, - - { ngx_string("listen"), - NGX_MAIL_SRV_CONF|NGX_CONF_TAKE12, - ngx_mail_core_listen, - 0, - 0, - NULL }, - - { ngx_string("protocol"), - NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_enum_slot, - NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_core_srv_conf_t, protocol), - &ngx_mail_core_procotol }, - - { ngx_string("imap_client_buffer"), - NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_size_slot, - NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_core_srv_conf_t, imap_client_buffer_size), - NULL }, +static ngx_command_t ngx_mail_smtp_commands[] = { { ngx_string("smtp_client_buffer"), NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, ngx_conf_set_size_slot, NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_core_srv_conf_t, smtp_client_buffer_size), + offsetof(ngx_mail_smtp_srv_conf_t, client_buffer_size), NULL }, { ngx_string("smtp_greeting_delay"), NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, ngx_conf_set_msec_slot, NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_core_srv_conf_t, smtp_greeting_delay), - NULL }, - - { ngx_string("so_keepalive"), - NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, - ngx_conf_set_flag_slot, - NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_core_srv_conf_t, so_keepalive), - NULL }, - - { ngx_string("timeout"), - NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_msec_slot, - NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_core_srv_conf_t, timeout), - NULL }, - - { ngx_string("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_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), + offsetof(ngx_mail_smtp_srv_conf_t, greeting_delay), 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_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, - ngx_conf_set_str_slot, - NGX_MAIL_SRV_CONF_OFFSET, - offsetof(ngx_mail_core_srv_conf_t, server_name), - NULL }, - - { ngx_string("auth"), - NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE, - ngx_conf_set_bitmask_slot, + ngx_mail_capabilities, 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("imap_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, imap_auth_methods), - &ngx_imap_auth_methods }, + offsetof(ngx_mail_smtp_srv_conf_t, capabilities), + NULL }, { 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 }, + offsetof(ngx_mail_smtp_srv_conf_t, auth_methods), + &ngx_mail_smtp_auth_methods }, ngx_null_command }; -static ngx_mail_module_t ngx_mail_core_module_ctx = { - ngx_mail_core_create_main_conf, /* create main configuration */ +static ngx_mail_module_t ngx_mail_smtp_module_ctx = { + &ngx_mail_smtp_protocol, /* protocol */ + + NULL, /* create main configuration */ NULL, /* init main configuration */ - ngx_mail_core_create_srv_conf, /* create server configuration */ - ngx_mail_core_merge_srv_conf /* merge server configuration */ + ngx_mail_smtp_create_srv_conf, /* create server configuration */ + ngx_mail_smtp_merge_srv_conf /* merge server configuration */ }; -ngx_module_t ngx_mail_core_module = { +ngx_module_t ngx_mail_smtp_module = { NGX_MODULE_V1, - &ngx_mail_core_module_ctx, /* module context */ - ngx_mail_core_commands, /* module directives */ + &ngx_mail_smtp_module_ctx, /* module context */ + ngx_mail_smtp_commands, /* module directives */ NGX_MAIL_MODULE, /* module type */ NULL, /* init master */ NULL, /* init module */ @@ -246,279 +108,104 @@ ngx_module_t ngx_mail_core_module = { static void * -ngx_mail_core_create_main_conf(ngx_conf_t *cf) +ngx_mail_smtp_create_srv_conf(ngx_conf_t *cf) { - ngx_mail_core_main_conf_t *cmcf; - - 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_mail_core_srv_conf_t *)) - != NGX_OK) - { - return NGX_CONF_ERROR; - } + ngx_mail_smtp_srv_conf_t *sscf; - if (ngx_array_init(&cmcf->listen, cf->pool, 4, sizeof(ngx_mail_listen_t)) - != NGX_OK) - { - return NGX_CONF_ERROR; - } - - return cmcf; -} - - -static void * -ngx_mail_core_create_srv_conf(ngx_conf_t *cf) -{ - ngx_mail_core_srv_conf_t *cscf; - - cscf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_core_srv_conf_t)); - if (cscf == NULL) { + sscf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_smtp_srv_conf_t)); + if (sscf == NULL) { return NULL; } - cscf->imap_client_buffer_size = NGX_CONF_UNSET_SIZE; - cscf->smtp_client_buffer_size = NGX_CONF_UNSET_SIZE; - cscf->protocol = NGX_CONF_UNSET_UINT; - cscf->timeout = NGX_CONF_UNSET_MSEC; - cscf->smtp_greeting_delay = NGX_CONF_UNSET_MSEC; - cscf->so_keepalive = NGX_CONF_UNSET; + sscf->client_buffer_size = NGX_CONF_UNSET_SIZE; + sscf->greeting_delay = NGX_CONF_UNSET_MSEC; - if (ngx_array_init(&cscf->pop3_capabilities, cf->pool, 4, sizeof(ngx_str_t)) - != NGX_OK) - { - return NULL; - } - - if (ngx_array_init(&cscf->imap_capabilities, cf->pool, 4, sizeof(ngx_str_t)) - != NGX_OK) - { - return NULL; - } - - if (ngx_array_init(&cscf->smtp_capabilities, cf->pool, 4, sizeof(ngx_str_t)) + if (ngx_array_init(&sscf->capabilities, cf->pool, 4, sizeof(ngx_str_t)) != NGX_OK) { return NULL; } - return cscf; + return sscf; } static char * -ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) +ngx_mail_smtp_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) { - ngx_mail_core_srv_conf_t *prev = parent; - ngx_mail_core_srv_conf_t *conf = child; + ngx_mail_smtp_srv_conf_t *prev = parent; + ngx_mail_smtp_srv_conf_t *conf = child; - u_char *p, *auth; - size_t size, stls_only_size; - ngx_str_t *c, *d; - ngx_uint_t i, m; + u_char *p, *auth; + size_t size; + ngx_str_t *c; + ngx_uint_t i, m; + ngx_mail_core_srv_conf_t *cscf; - ngx_conf_merge_size_value(conf->imap_client_buffer_size, - prev->imap_client_buffer_size, - (size_t) ngx_pagesize); - ngx_conf_merge_size_value(conf->smtp_client_buffer_size, - prev->smtp_client_buffer_size, + ngx_conf_merge_size_value(conf->client_buffer_size, + prev->client_buffer_size, (size_t) ngx_pagesize); - ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 60000); - ngx_conf_merge_msec_value(conf->smtp_greeting_delay, - prev->smtp_greeting_delay, 0); - - ngx_conf_merge_uint_value(conf->protocol, prev->protocol, - NGX_MAIL_IMAP_PROTOCOL); - ngx_conf_merge_value(conf->so_keepalive, prev->so_keepalive, 0); + ngx_conf_merge_msec_value(conf->greeting_delay, + prev->greeting_delay, 0); - 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->imap_auth_methods, - prev->imap_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_merge_bitmask_value(conf->auth_methods, + prev->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, ""); - - if (conf->server_name.len == 0) { - conf->server_name.data = ngx_palloc(cf->pool, NGX_MAXHOSTNAMELEN); - if (conf->server_name.data == NULL) { - return NGX_CONF_ERROR; - } - - if (gethostname((char *) conf->server_name.data, NGX_MAXHOSTNAMELEN) - == -1) - { - ngx_conf_log_error(NGX_LOG_EMERG, cf, ngx_errno, - "gethostname() failed"); - return NGX_CONF_ERROR; - } - - conf->server_name.len = ngx_strlen(conf->server_name.data); - } - - - if (conf->pop3_capabilities.nelts == 0) { - conf->pop3_capabilities = prev->pop3_capabilities; - } - - if (conf->pop3_capabilities.nelts == 0) { + cscf = ngx_mail_conf_get_module_srv_conf(cf, ngx_mail_core_module); - for (d = ngx_pop3_default_capabilities; d->len; d++) { - c = ngx_array_push(&conf->pop3_capabilities); - if (c == NULL) { - return NGX_CONF_ERROR; - } - - *c = *d; - } - } - - 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->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) { - size += sizeof("SASL LOGIN PLAIN CRAM-MD5" CRLF) - 1; - - } else { - size += sizeof("SASL LOGIN PLAIN" CRLF) - 1; - } + size = sizeof("220 ESMTP ready" CRLF) - 1 + cscf->server_name.len; p = ngx_palloc(cf->pool, size); if (p == NULL) { return NGX_CONF_ERROR; } - conf->pop3_capability.len = size; - conf->pop3_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++) { - p = ngx_cpymem(p, c[i].data, c[i].len); - *p++ = CR; *p++ = LF; - } + conf->greeting.len = size; + conf->greeting.data = p; - 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); - - } else { - p = ngx_cpymem(p, "SASL LOGIN PLAIN" CRLF, - sizeof("SASL LOGIN PLAIN" CRLF) - 1); - } - - *p++ = '.'; *p++ = CR; *p = LF; + *p++ = '2'; *p++ = '2'; *p++ = '0'; *p++ = ' '; + p = ngx_cpymem(p, cscf->server_name.data, cscf->server_name.len); + ngx_memcpy(p, " ESMTP ready" CRLF, sizeof(" ESMTP ready" CRLF) - 1); - size += sizeof("STLS" CRLF) - 1; + size = sizeof("250 " CRLF) - 1 + cscf->server_name.len; p = ngx_palloc(cf->pool, size); if (p == NULL) { return NGX_CONF_ERROR; } - conf->pop3_starttls_capability.len = size; - conf->pop3_starttls_capability.data = p; + conf->server_name.len = size; + conf->server_name.data = p; - p = ngx_cpymem(p, conf->pop3_capability.data, - conf->pop3_capability.len - (sizeof("." CRLF) - 1)); - - p = ngx_cpymem(p, "STLS" CRLF, sizeof("STLS" CRLF) - 1); - *p++ = '.'; *p++ = CR; *p = LF; + *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = ' '; + p = ngx_cpymem(p, cscf->server_name.data, cscf->server_name.len); + *p++ = CR; *p = LF; - if (conf->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED) { - conf->pop3_auth_capability = ngx_pop3_auth_cram_md5_capability; - - } else { - conf->pop3_auth_capability = ngx_pop3_auth_plain_capability; - } - - - p = ngx_palloc(cf->pool, stls_only_size); - if (p == NULL) { - return NGX_CONF_ERROR; + if (conf->capabilities.nelts == 0) { + conf->capabilities = prev->capabilities; } - 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; - + size = sizeof("250-") - 1 + cscf->server_name.len + sizeof(CRLF) - 1 + + sizeof("250 AUTH") - 1 + sizeof(CRLF) - 1; - if (conf->imap_capabilities.nelts == 0) { - conf->imap_capabilities = prev->imap_capabilities; - } - - if (conf->imap_capabilities.nelts == 0) { - - for (d = ngx_imap_default_capabilities; d->len; d++) { - c = ngx_array_push(&conf->imap_capabilities); - if (c == NULL) { - return NGX_CONF_ERROR; - } - - *c = *d; - } - } - - size = sizeof("* CAPABILITY" CRLF) - 1; - - c = conf->imap_capabilities.elts; - for (i = 0; i < conf->imap_capabilities.nelts; i++) { - size += 1 + c[i].len; + c = conf->capabilities.elts; + for (i = 0; i < conf->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->imap_auth_methods) { - size += 1 + ngx_imap_auth_methods_names[i].len; + if (m & conf->auth_methods) { + size += 1 + ngx_mail_smtp_auth_methods_names[i].len; } } @@ -527,130 +214,14 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t return NGX_CONF_ERROR; } - conf->imap_capability.len = size; - conf->imap_capability.data = p; - - p = ngx_cpymem(p, "* CAPABILITY", sizeof("* CAPABILITY") - 1); - - for (i = 0; i < conf->imap_capabilities.nelts; i++) { - *p++ = ' '; - p = ngx_cpymem(p, c[i].data, c[i].len); - } - - auth = p; - - for (m = NGX_MAIL_AUTH_PLAIN_ENABLED, i = 0; - m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; - m <<= 1, i++) - { - if (m & conf->imap_auth_methods) { - *p++ = ' '; - p = ngx_cpymem(p, ngx_imap_auth_methods_names[i].data, - ngx_imap_auth_methods_names[i].len); - } - } - - *p++ = CR; *p = LF; - - - size += sizeof(" STARTTLS") - 1; - - p = ngx_palloc(cf->pool, size); - if (p == NULL) { - return NGX_CONF_ERROR; - } - - conf->imap_starttls_capability.len = size; - conf->imap_starttls_capability.data = p; - - p = ngx_cpymem(p, conf->imap_capability.data, - conf->imap_capability.len - (sizeof(CRLF) - 1)); - p = ngx_cpymem(p, " STARTTLS", sizeof(" STARTTLS") - 1); - *p++ = CR; *p = LF; - - - size = (auth - conf->imap_capability.data) + sizeof(CRLF) - 1 - + sizeof(" STARTTLS LOGINDISABLED") - 1; - - p = ngx_palloc(cf->pool, size); - if (p == NULL) { - return NGX_CONF_ERROR; - } - - conf->imap_starttls_only_capability.len = size; - conf->imap_starttls_only_capability.data = p; - - p = ngx_cpymem(p, conf->imap_capability.data, - auth - conf->imap_capability.data); - p = ngx_cpymem(p, " STARTTLS LOGINDISABLED", - sizeof(" STARTTLS LOGINDISABLED") - 1); - *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; + conf->capability.len = size; + conf->capability.data = p; *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = '-'; - p = ngx_cpymem(p, conf->server_name.data, conf->server_name.len); + p = ngx_cpymem(p, cscf->server_name.data, cscf->server_name.len); *p++ = CR; *p++ = LF; - for (i = 0; i < conf->smtp_capabilities.nelts; i++) { + for (i = 0; i < conf->capabilities.nelts; i++) { *p++ = '2'; *p++ = '5'; *p++ = '0'; *p++ = '-'; p = ngx_cpymem(p, c[i].data, c[i].len); *p++ = CR; *p++ = LF; @@ -665,10 +236,10 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t m <= NGX_MAIL_AUTH_CRAM_MD5_ENABLED; m <<= 1, i++) { - if (m & conf->smtp_auth_methods) { + if (m & conf->auth_methods) { *p++ = ' '; - p = ngx_cpymem(p, ngx_smtp_auth_methods_names[i].data, - ngx_smtp_auth_methods_names[i].len); + p = ngx_cpymem(p, ngx_mail_smtp_auth_methods_names[i].data, + ngx_mail_smtp_auth_methods_names[i].len); } } @@ -681,20 +252,20 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t return NGX_CONF_ERROR; } - conf->smtp_starttls_capability.len = size; - conf->smtp_starttls_capability.data = p; + conf->starttls_capability.len = size; + conf->starttls_capability.data = p; - p = ngx_cpymem(p, conf->smtp_capability.data, - conf->smtp_capability.len); + p = ngx_cpymem(p, conf->capability.data, + conf->capability.len); p = ngx_cpymem(p, "250 STARTTLS" CRLF, sizeof("250 STARTTLS" CRLF) - 1); *p++ = CR; *p = LF; - p = conf->smtp_starttls_capability.data - + (auth - conf->smtp_capability.data) + 3; + p = conf->starttls_capability.data + + (auth - conf->capability.data) + 3; *p = '-'; - size = (auth - conf->smtp_capability.data) + size = (auth - conf->capability.data) + sizeof("250 STARTTLS" CRLF) - 1; p = ngx_palloc(cf->pool, size); @@ -702,183 +273,13 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t return NGX_CONF_ERROR; } - conf->smtp_starttls_only_capability.len = size; - conf->smtp_starttls_only_capability.data = p; + conf->starttls_only_capability.len = size; + conf->starttls_only_capability.data = p; - p = ngx_cpymem(p, conf->smtp_capability.data, - auth - conf->smtp_capability.data); + p = ngx_cpymem(p, conf->capability.data, + auth - conf->capability.data); ngx_memcpy(p, "250 STARTTLS" CRLF, sizeof("250 STARTTLS" CRLF) - 1); return NGX_CONF_OK; } - - -static char * -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_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_mail_conf_ctx_t)); - if (ctx == NULL) { - return NGX_CONF_ERROR; - } - - 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_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_MAIL_MODULE) { - continue; - } - - module = ngx_modules[m]->ctx; - - if (module->create_srv_conf) { - mconf = module->create_srv_conf(cf); - if (mconf == NULL) { - return NGX_CONF_ERROR; - } - - ctx->srv_conf[ngx_modules[m]->ctx_index] = mconf; - } - } - - /* the server configuration context */ - - cscf = ctx->srv_conf[ngx_mail_core_module.ctx_index]; - cscf->ctx = ctx; - - cmcf = ctx->main_conf[ngx_mail_core_module.ctx_index]; - - cscfp = ngx_array_push(&cmcf->servers); - if (cscfp == NULL) { - return NGX_CONF_ERROR; - } - - *cscfp = cscf; - - - /* parse inside server{} */ - - pcf = *cf; - cf->ctx = ctx; - cf->cmd_type = NGX_MAIL_SRV_CONF; - - rv = ngx_conf_parse(cf, NULL); - - *cf = pcf; - - return rv; -} - - -/* AF_INET only */ - -static char * -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_mail_listen_t *imls; - ngx_mail_core_main_conf_t *cmcf; - - value = cf->args->elts; - - ngx_memzero(&u, sizeof(ngx_url_t)); - - u.url = value[1]; - u.listen = 1; - - if (ngx_parse_url(cf, &u) != NGX_OK) { - if (u.err) { - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "%s in \"%V\" of the \"listen\" directive", - u.err, &u.url); - } - - return NGX_CONF_ERROR; - } - - cmcf = ngx_mail_conf_get_module_main_conf(cf, ngx_mail_core_module); - - imls = cmcf->listen.elts; - - for (i = 0; i < cmcf->listen.nelts; i++) { - - if (imls[i].addr != u.addr.in_addr || imls[i].port != u.port) { - continue; - } - - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "duplicate \"%V\" address and port pair", &u.url); - return NGX_CONF_ERROR; - } - - imls = ngx_array_push(&cmcf->listen); - if (imls == NULL) { - return NGX_CONF_ERROR; - } - - ngx_memzero(imls, sizeof(ngx_mail_listen_t)); - - imls->addr = u.addr.in_addr; - imls->port = u.port; - imls->family = AF_INET; - imls->ctx = cf->ctx; - - if (cf->args->nelts == 2) { - return NGX_CONF_OK; - } - - if (ngx_strcmp(value[2].data, "bind") == 0) { - imls->bind = 1; - return NGX_CONF_OK; - } - - ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "the invalid \"%V\" parameter", &value[2]); - return NGX_CONF_ERROR; -} - - -static char * -ngx_mail_core_capability(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) -{ - char *p = conf; - - ngx_str_t *c, *value; - ngx_uint_t i; - ngx_array_t *a; - - a = (ngx_array_t *) (p + cmd->offset); - - value = cf->args->elts; - - for (i = 1; i < cf->args->nelts; i++) { - c = ngx_array_push(a); - if (c == NULL) { - return NGX_CONF_ERROR; - } - - *c = value[i]; - } - - return NGX_CONF_OK; -} diff --git a/src/mail/ngx_mail_smtp_module.h b/src/mail/ngx_mail_smtp_module.h new file mode 100644 --- /dev/null +++ b/src/mail/ngx_mail_smtp_module.h @@ -0,0 +1,44 @@ + +/* + * Copyright (C) Igor Sysoev + */ + + +#ifndef _NGX_MAIL_SMTP_MODULE_H_INCLUDED_ +#define _NGX_MAIL_SMTP_MODULE_H_INCLUDED_ + + +#include +#include +#include +#include + + +typedef struct { + ngx_msec_t greeting_delay; + + size_t client_buffer_size; + + ngx_str_t capability; + ngx_str_t starttls_capability; + ngx_str_t starttls_only_capability; + + ngx_str_t server_name; + ngx_str_t greeting; + + ngx_uint_t auth_methods; + + ngx_array_t capabilities; +} ngx_mail_smtp_srv_conf_t; + + +void ngx_mail_smtp_init_session(ngx_mail_session_t *s, ngx_connection_t *c); +void ngx_mail_smtp_init_protocol(ngx_event_t *rev); +void ngx_mail_smtp_auth_state(ngx_event_t *rev); +ngx_int_t ngx_mail_smtp_parse_command(ngx_mail_session_t *s); + + +extern ngx_module_t ngx_mail_smtp_module; + + +#endif /* _NGX_MAIL_SMTP_MODULE_H_INCLUDED_ */ diff --git a/src/mail/ngx_mail_ssl_module.c b/src/mail/ngx_mail_ssl_module.c --- a/src/mail/ngx_mail_ssl_module.c +++ b/src/mail/ngx_mail_ssl_module.c @@ -120,6 +120,8 @@ static ngx_command_t ngx_mail_ssl_comma static ngx_mail_module_t ngx_mail_ssl_module_ctx = { + NULL, /* protocol */ + NULL, /* create main configuration */ NULL, /* init main configuration */