mirror of
https://github.com/nginx/nginx.git
synced 2025-07-25 22:56:59 +08:00
IMAP AUTHENTICATE
patch by Maxim Dounin
This commit is contained in:
parent
810dc1652d
commit
f4283a91f1
@ -100,6 +100,7 @@ typedef struct {
|
|||||||
ngx_str_t smtp_greeting;
|
ngx_str_t smtp_greeting;
|
||||||
|
|
||||||
ngx_uint_t pop3_auth_methods;
|
ngx_uint_t pop3_auth_methods;
|
||||||
|
ngx_uint_t imap_auth_methods;
|
||||||
ngx_uint_t smtp_auth_methods;
|
ngx_uint_t smtp_auth_methods;
|
||||||
|
|
||||||
ngx_array_t pop3_capabilities;
|
ngx_array_t pop3_capabilities;
|
||||||
@ -134,6 +135,10 @@ typedef enum {
|
|||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ngx_imap_start = 0,
|
ngx_imap_start = 0,
|
||||||
|
ngx_imap_auth_login_username,
|
||||||
|
ngx_imap_auth_login_password,
|
||||||
|
ngx_imap_auth_plain,
|
||||||
|
ngx_imap_auth_cram_md5,
|
||||||
ngx_imap_login,
|
ngx_imap_login,
|
||||||
ngx_imap_user,
|
ngx_imap_user,
|
||||||
ngx_imap_passwd
|
ngx_imap_passwd
|
||||||
@ -216,45 +221,47 @@ typedef struct {
|
|||||||
} ngx_mail_log_ctx_t;
|
} ngx_mail_log_ctx_t;
|
||||||
|
|
||||||
|
|
||||||
#define NGX_POP3_USER 1
|
#define NGX_POP3_USER 1
|
||||||
#define NGX_POP3_PASS 2
|
#define NGX_POP3_PASS 2
|
||||||
#define NGX_POP3_CAPA 3
|
#define NGX_POP3_CAPA 3
|
||||||
#define NGX_POP3_QUIT 4
|
#define NGX_POP3_QUIT 4
|
||||||
#define NGX_POP3_NOOP 5
|
#define NGX_POP3_NOOP 5
|
||||||
#define NGX_POP3_STLS 6
|
#define NGX_POP3_STLS 6
|
||||||
#define NGX_POP3_APOP 7
|
#define NGX_POP3_APOP 7
|
||||||
#define NGX_POP3_AUTH 8
|
#define NGX_POP3_AUTH 8
|
||||||
#define NGX_POP3_STAT 9
|
#define NGX_POP3_STAT 9
|
||||||
#define NGX_POP3_LIST 10
|
#define NGX_POP3_LIST 10
|
||||||
#define NGX_POP3_RETR 11
|
#define NGX_POP3_RETR 11
|
||||||
#define NGX_POP3_DELE 12
|
#define NGX_POP3_DELE 12
|
||||||
#define NGX_POP3_RSET 13
|
#define NGX_POP3_RSET 13
|
||||||
#define NGX_POP3_TOP 14
|
#define NGX_POP3_TOP 14
|
||||||
#define NGX_POP3_UIDL 15
|
#define NGX_POP3_UIDL 15
|
||||||
|
|
||||||
|
|
||||||
#define NGX_IMAP_LOGIN 1
|
#define NGX_IMAP_LOGIN 1
|
||||||
#define NGX_IMAP_LOGOUT 2
|
#define NGX_IMAP_LOGOUT 2
|
||||||
#define NGX_IMAP_CAPABILITY 3
|
#define NGX_IMAP_CAPABILITY 3
|
||||||
#define NGX_IMAP_NOOP 4
|
#define NGX_IMAP_NOOP 4
|
||||||
#define NGX_IMAP_STARTTLS 5
|
#define NGX_IMAP_STARTTLS 5
|
||||||
|
|
||||||
#define NGX_IMAP_NEXT 6
|
#define NGX_IMAP_NEXT 6
|
||||||
|
|
||||||
|
#define NGX_IMAP_AUTHENTICATE 7
|
||||||
|
|
||||||
|
|
||||||
#define NGX_SMTP_HELO 1
|
#define NGX_SMTP_HELO 1
|
||||||
#define NGX_SMTP_EHLO 2
|
#define NGX_SMTP_EHLO 2
|
||||||
#define NGX_SMTP_AUTH 3
|
#define NGX_SMTP_AUTH 3
|
||||||
#define NGX_SMTP_QUIT 4
|
#define NGX_SMTP_QUIT 4
|
||||||
#define NGX_SMTP_NOOP 5
|
#define NGX_SMTP_NOOP 5
|
||||||
#define NGX_SMTP_MAIL 6
|
#define NGX_SMTP_MAIL 6
|
||||||
#define NGX_SMTP_RSET 7
|
#define NGX_SMTP_RSET 7
|
||||||
#define NGX_SMTP_RCPT 8
|
#define NGX_SMTP_RCPT 8
|
||||||
#define NGX_SMTP_DATA 9
|
#define NGX_SMTP_DATA 9
|
||||||
#define NGX_SMTP_VRFY 10
|
#define NGX_SMTP_VRFY 10
|
||||||
#define NGX_SMTP_EXPN 11
|
#define NGX_SMTP_EXPN 11
|
||||||
#define NGX_SMTP_HELP 12
|
#define NGX_SMTP_HELP 12
|
||||||
#define NGX_SMTP_STARTTLS 13
|
#define NGX_SMTP_STARTTLS 13
|
||||||
|
|
||||||
|
|
||||||
#define NGX_MAIL_AUTH_PLAIN 0
|
#define NGX_MAIL_AUTH_PLAIN 0
|
||||||
|
@ -54,6 +54,14 @@ static ngx_conf_bitmask_t ngx_pop3_auth_methods[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
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[] = {
|
static ngx_conf_bitmask_t ngx_smtp_auth_methods[] = {
|
||||||
{ ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED },
|
{ ngx_string("plain"), NGX_MAIL_AUTH_PLAIN_ENABLED },
|
||||||
{ ngx_string("login"), NGX_MAIL_AUTH_LOGIN_ENABLED },
|
{ ngx_string("login"), NGX_MAIL_AUTH_LOGIN_ENABLED },
|
||||||
@ -62,6 +70,14 @@ static ngx_conf_bitmask_t ngx_smtp_auth_methods[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
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_smtp_auth_methods_names[] = {
|
||||||
ngx_string("PLAIN"),
|
ngx_string("PLAIN"),
|
||||||
ngx_string("LOGIN"),
|
ngx_string("LOGIN"),
|
||||||
@ -172,6 +188,13 @@ static ngx_command_t ngx_mail_core_commands[] = {
|
|||||||
offsetof(ngx_mail_core_srv_conf_t, pop3_auth_methods),
|
offsetof(ngx_mail_core_srv_conf_t, pop3_auth_methods),
|
||||||
&ngx_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_string("smtp_auth"),
|
||||||
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
|
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
|
||||||
ngx_conf_set_bitmask_slot,
|
ngx_conf_set_bitmask_slot,
|
||||||
@ -297,6 +320,11 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||||||
(NGX_CONF_BITMASK_SET
|
(NGX_CONF_BITMASK_SET
|
||||||
|NGX_MAIL_AUTH_PLAIN_ENABLED));
|
|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,
|
ngx_conf_merge_bitmask_value(conf->smtp_auth_methods,
|
||||||
prev->smtp_auth_methods,
|
prev->smtp_auth_methods,
|
||||||
(NGX_CONF_BITMASK_SET
|
(NGX_CONF_BITMASK_SET
|
||||||
@ -463,6 +491,15 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||||||
size += 1 + c[i].len;
|
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);
|
p = ngx_palloc(cf->pool, size);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
return NGX_CONF_ERROR;
|
return NGX_CONF_ERROR;
|
||||||
@ -478,6 +515,19 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||||||
p = ngx_cpymem(p, c[i].data, c[i].len);
|
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;
|
*p++ = CR; *p = LF;
|
||||||
|
|
||||||
|
|
||||||
@ -497,7 +547,8 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||||||
*p++ = CR; *p = LF;
|
*p++ = CR; *p = LF;
|
||||||
|
|
||||||
|
|
||||||
size += sizeof(" LOGINDISABLED") - 1;
|
size = (auth - conf->imap_capability.data) + sizeof(CRLF) - 1
|
||||||
|
+ sizeof(" STARTTLS LOGINDISABLED") - 1;
|
||||||
|
|
||||||
p = ngx_palloc(cf->pool, size);
|
p = ngx_palloc(cf->pool, size);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
@ -507,9 +558,10 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||||||
conf->imap_starttls_only_capability.len = size;
|
conf->imap_starttls_only_capability.len = size;
|
||||||
conf->imap_starttls_only_capability.data = p;
|
conf->imap_starttls_only_capability.data = p;
|
||||||
|
|
||||||
p = ngx_cpymem(p, conf->imap_starttls_capability.data,
|
p = ngx_cpymem(p, conf->imap_capability.data,
|
||||||
conf->imap_starttls_capability.len - (sizeof(CRLF) - 1));
|
auth - conf->imap_capability.data);
|
||||||
p = ngx_cpymem(p, " LOGINDISABLED", sizeof(" LOGINDISABLED") - 1);
|
p = ngx_cpymem(p, " STARTTLS LOGINDISABLED",
|
||||||
|
sizeof(" STARTTLS LOGINDISABLED") - 1);
|
||||||
*p++ = CR; *p = LF;
|
*p++ = CR; *p = LF;
|
||||||
|
|
||||||
|
|
||||||
|
@ -280,6 +280,9 @@ ngx_mail_init_session(ngx_connection_t *c)
|
|||||||
&& (cscf->pop3_auth_methods
|
&& (cscf->pop3_auth_methods
|
||||||
& (NGX_MAIL_AUTH_APOP_ENABLED|NGX_MAIL_AUTH_CRAM_MD5_ENABLED)))
|
& (NGX_MAIL_AUTH_APOP_ENABLED|NGX_MAIL_AUTH_CRAM_MD5_ENABLED)))
|
||||||
|
|
||||||
|
|| (s->protocol == NGX_MAIL_IMAP_PROTOCOL
|
||||||
|
&& (cscf->imap_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED))
|
||||||
|
|
||||||
|| (s->protocol == NGX_MAIL_SMTP_PROTOCOL
|
|| (s->protocol == NGX_MAIL_SMTP_PROTOCOL
|
||||||
&& (cscf->smtp_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED)))
|
&& (cscf->smtp_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED)))
|
||||||
{
|
{
|
||||||
@ -985,7 +988,7 @@ ngx_imap_auth_state(ngx_event_t *rev)
|
|||||||
{
|
{
|
||||||
u_char *p, *last, *text, *dst, *src, *end;
|
u_char *p, *last, *text, *dst, *src, *end;
|
||||||
ssize_t text_len, last_len;
|
ssize_t text_len, last_len;
|
||||||
ngx_str_t *arg;
|
ngx_str_t *arg, salt;
|
||||||
ngx_int_t rc;
|
ngx_int_t rc;
|
||||||
ngx_uint_t tag, i;
|
ngx_uint_t tag, i;
|
||||||
ngx_connection_t *c;
|
ngx_connection_t *c;
|
||||||
@ -1055,113 +1058,342 @@ ngx_imap_auth_state(ngx_event_t *rev)
|
|||||||
s->backslash = 0;
|
s->backslash = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (s->command) {
|
switch (s->mail_state) {
|
||||||
|
|
||||||
case NGX_IMAP_LOGIN:
|
case ngx_imap_start:
|
||||||
|
|
||||||
|
switch (s->command) {
|
||||||
|
|
||||||
|
case NGX_IMAP_LOGIN:
|
||||||
|
|
||||||
#if (NGX_MAIL_SSL)
|
#if (NGX_MAIL_SSL)
|
||||||
|
|
||||||
if (c->ssl == NULL) {
|
if (c->ssl == NULL) {
|
||||||
sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
|
sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
|
||||||
|
|
||||||
if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
|
if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
|
||||||
|
rc = NGX_MAIL_PARSE_INVALID_COMMAND;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
arg = s->args.elts;
|
||||||
|
|
||||||
|
if (s->args.nelts == 2 && arg[0].len) {
|
||||||
|
|
||||||
|
s->login.len = arg[0].len;
|
||||||
|
s->login.data = ngx_palloc(c->pool, s->login.len);
|
||||||
|
if (s->login.data == NULL) {
|
||||||
|
ngx_mail_session_internal_server_error(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_memcpy(s->login.data, arg[0].data, s->login.len);
|
||||||
|
|
||||||
|
s->passwd.len = arg[1].len;
|
||||||
|
s->passwd.data = ngx_palloc(c->pool, s->passwd.len);
|
||||||
|
if (s->passwd.data == NULL) {
|
||||||
|
ngx_mail_session_internal_server_error(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_memcpy(s->passwd.data, arg[1].data, s->passwd.len);
|
||||||
|
|
||||||
|
#if (NGX_DEBUG_MAIL_PASSWD)
|
||||||
|
ngx_log_debug2(NGX_LOG_DEBUG_MAIL, c->log, 0,
|
||||||
|
"imap login:\"%V\" passwd:\"%V\"",
|
||||||
|
&s->login, &s->passwd);
|
||||||
|
#else
|
||||||
|
ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
|
||||||
|
"imap login:\"%V\"", &s->login);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ngx_mail_do_auth(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = NGX_MAIL_PARSE_INVALID_COMMAND;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NGX_IMAP_AUTHENTICATE:
|
||||||
|
|
||||||
|
#if (NGX_MAIL_SSL)
|
||||||
|
|
||||||
|
if (c->ssl == NULL) {
|
||||||
|
sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
|
||||||
|
|
||||||
|
if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
|
||||||
|
rc = NGX_MAIL_PARSE_INVALID_COMMAND;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (s->args.nelts != 1) {
|
||||||
rc = NGX_MAIL_PARSE_INVALID_COMMAND;
|
rc = NGX_MAIL_PARSE_INVALID_COMMAND;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
arg = s->args.elts;
|
||||||
|
|
||||||
|
if (arg[0].len == 5) {
|
||||||
|
|
||||||
|
if (ngx_strncasecmp(arg[0].data, (u_char *) "LOGIN", 5)
|
||||||
|
== 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
s->mail_state = ngx_imap_auth_login_username;
|
||||||
|
|
||||||
|
last_len = sizeof(pop3_username) - 1;
|
||||||
|
last = pop3_username;
|
||||||
|
tag = 0;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
} else if (ngx_strncasecmp(arg[0].data, (u_char *) "PLAIN",
|
||||||
|
5)
|
||||||
|
== 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
s->mail_state = ngx_imap_auth_plain;
|
||||||
|
|
||||||
|
last_len = sizeof(pop3_next) - 1;
|
||||||
|
last = pop3_next;
|
||||||
|
tag = 0;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (arg[0].len == 8
|
||||||
|
&& ngx_strncasecmp(arg[0].data,
|
||||||
|
(u_char *) "CRAM-MD5", 8)
|
||||||
|
== 0)
|
||||||
|
{
|
||||||
|
cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
|
||||||
|
|
||||||
|
if (!(cscf->imap_auth_methods
|
||||||
|
& NGX_MAIL_AUTH_CRAM_MD5_ENABLED)
|
||||||
|
|| s->args.nelts != 1)
|
||||||
|
{
|
||||||
|
rc = NGX_MAIL_PARSE_INVALID_COMMAND;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
s->mail_state = ngx_imap_auth_cram_md5;
|
||||||
|
|
||||||
|
last = ngx_palloc(c->pool,
|
||||||
|
sizeof("+ " CRLF) - 1
|
||||||
|
+ ngx_base64_encoded_length(s->salt.len));
|
||||||
|
if (last == NULL) {
|
||||||
|
ngx_mail_session_internal_server_error(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
last[0] = '+'; last[1]= ' ';
|
||||||
|
salt.data = &last[2];
|
||||||
|
s->salt.len -= 2;
|
||||||
|
|
||||||
|
ngx_encode_base64(&salt, &s->salt);
|
||||||
|
|
||||||
|
s->salt.len += 2;
|
||||||
|
last_len = 2 + salt.len;
|
||||||
|
last[last_len++] = CR; last[last_len++] = LF;
|
||||||
|
tag = 0;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = NGX_MAIL_PARSE_INVALID_COMMAND;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NGX_IMAP_CAPABILITY:
|
||||||
|
cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
|
||||||
|
|
||||||
|
#if (NGX_MAIL_SSL)
|
||||||
|
|
||||||
|
if (c->ssl == NULL) {
|
||||||
|
sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
|
||||||
|
|
||||||
|
if (sslcf->starttls == NGX_MAIL_STARTTLS_ON) {
|
||||||
|
text_len = cscf->imap_starttls_capability.len;
|
||||||
|
text = cscf->imap_starttls_capability.data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
|
||||||
|
text_len = cscf->imap_starttls_only_capability.len;
|
||||||
|
text = cscf->imap_starttls_only_capability.data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
text_len = cscf->imap_capability.len;
|
||||||
|
text = cscf->imap_capability.data;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NGX_IMAP_LOGOUT:
|
||||||
|
s->quit = 1;
|
||||||
|
text = imap_bye;
|
||||||
|
text_len = sizeof(imap_bye) - 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NGX_IMAP_NOOP:
|
||||||
|
break;
|
||||||
|
|
||||||
|
#if (NGX_MAIL_SSL)
|
||||||
|
|
||||||
|
case NGX_IMAP_STARTTLS:
|
||||||
|
if (c->ssl == NULL) {
|
||||||
|
sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
|
||||||
|
if (sslcf->starttls) {
|
||||||
|
c->read->handler = ngx_mail_starttls_handler;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = NGX_MAIL_PARSE_INVALID_COMMAND;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
rc = NGX_MAIL_PARSE_INVALID_COMMAND;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ngx_imap_auth_login_username:
|
||||||
|
arg = s->args.elts;
|
||||||
|
s->mail_state = ngx_imap_auth_login_password;
|
||||||
|
|
||||||
|
ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
|
||||||
|
"imap auth login username: \"%V\"", &arg[0]);
|
||||||
|
|
||||||
|
s->login.data = ngx_palloc(c->pool,
|
||||||
|
ngx_base64_decoded_length(arg[0].len));
|
||||||
|
if (s->login.data == NULL){
|
||||||
|
ngx_mail_session_internal_server_error(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ngx_decode_base64(&s->login, &arg[0]) != NGX_OK) {
|
||||||
|
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
||||||
|
"client sent invalid base64 encoding "
|
||||||
|
"in AUTH LOGIN command");
|
||||||
|
rc = NGX_MAIL_PARSE_INVALID_COMMAND;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
|
||||||
|
"imap auth login username: \"%V\"", &s->login);
|
||||||
|
|
||||||
|
last_len = sizeof(pop3_password) - 1;
|
||||||
|
last = pop3_password;
|
||||||
|
tag = 0;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ngx_imap_auth_login_password:
|
||||||
arg = s->args.elts;
|
arg = s->args.elts;
|
||||||
|
|
||||||
if (s->args.nelts == 2 && arg[0].len) {
|
|
||||||
|
|
||||||
s->login.len = arg[0].len;
|
|
||||||
s->login.data = ngx_palloc(c->pool, s->login.len);
|
|
||||||
if (s->login.data == NULL) {
|
|
||||||
ngx_mail_session_internal_server_error(s);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngx_memcpy(s->login.data, arg[0].data, s->login.len);
|
|
||||||
|
|
||||||
s->passwd.len = arg[1].len;
|
|
||||||
s->passwd.data = ngx_palloc(c->pool, s->passwd.len);
|
|
||||||
if (s->passwd.data == NULL) {
|
|
||||||
ngx_mail_session_internal_server_error(s);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngx_memcpy(s->passwd.data, arg[1].data, s->passwd.len);
|
|
||||||
|
|
||||||
#if (NGX_DEBUG_MAIL_PASSWD)
|
#if (NGX_DEBUG_MAIL_PASSWD)
|
||||||
ngx_log_debug2(NGX_LOG_DEBUG_MAIL, c->log, 0,
|
ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
|
||||||
"imap login:\"%V\" passwd:\"%V\"",
|
"imap auth login password: \"%V\"", &arg[0]);
|
||||||
&s->login, &s->passwd);
|
|
||||||
#else
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
|
|
||||||
"imap login:\"%V\"", &s->login);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
s->passwd.data = ngx_palloc(c->pool,
|
||||||
|
ngx_base64_decoded_length(arg[0].len));
|
||||||
|
if (s->passwd.data == NULL){
|
||||||
|
ngx_mail_session_internal_server_error(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ngx_decode_base64(&s->passwd, &arg[0]) != NGX_OK) {
|
||||||
|
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
||||||
|
"client sent invalid base64 encoding "
|
||||||
|
"in AUTH LOGIN command");
|
||||||
|
rc = NGX_MAIL_PARSE_INVALID_COMMAND;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (NGX_DEBUG_MAIL_PASSWD)
|
||||||
|
ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
|
||||||
|
"imap auth login password: \"%V\"", &s->passwd);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ngx_mail_do_auth(s);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case ngx_imap_auth_plain:
|
||||||
|
arg = s->args.elts;
|
||||||
|
|
||||||
|
rc = ngx_mail_decode_auth_plain(s, &arg[0]);
|
||||||
|
|
||||||
|
if (rc == NGX_OK) {
|
||||||
ngx_mail_do_auth(s);
|
ngx_mail_do_auth(s);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = NGX_MAIL_PARSE_INVALID_COMMAND;
|
if (rc == NGX_ERROR) {
|
||||||
break;
|
ngx_mail_session_internal_server_error(s);
|
||||||
|
return;
|
||||||
case NGX_IMAP_CAPABILITY:
|
|
||||||
cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
|
|
||||||
|
|
||||||
#if (NGX_MAIL_SSL)
|
|
||||||
|
|
||||||
if (c->ssl == NULL) {
|
|
||||||
sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
|
|
||||||
|
|
||||||
if (sslcf->starttls == NGX_MAIL_STARTTLS_ON) {
|
|
||||||
text_len = cscf->imap_starttls_capability.len;
|
|
||||||
text = cscf->imap_starttls_capability.data;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
|
|
||||||
text_len = cscf->imap_starttls_only_capability.len;
|
|
||||||
text = cscf->imap_starttls_only_capability.data;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
text_len = cscf->imap_capability.len;
|
/* rc == NGX_MAIL_PARSE_INVALID_COMMAND */
|
||||||
text = cscf->imap_capability.data;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NGX_IMAP_LOGOUT:
|
case ngx_imap_auth_cram_md5:
|
||||||
s->quit = 1;
|
arg = s->args.elts;
|
||||||
text = imap_bye;
|
|
||||||
text_len = sizeof(imap_bye) - 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NGX_IMAP_NOOP:
|
ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
|
||||||
break;
|
"imap auth cram-md5: \"%V\"", &arg[0]);
|
||||||
|
|
||||||
#if (NGX_MAIL_SSL)
|
s->login.data = ngx_palloc(c->pool,
|
||||||
|
ngx_base64_decoded_length(arg[0].len));
|
||||||
|
if (s->login.data == NULL){
|
||||||
|
ngx_mail_session_internal_server_error(s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case NGX_IMAP_STARTTLS:
|
if (ngx_decode_base64(&s->login, &arg[0]) != NGX_OK) {
|
||||||
if (c->ssl == NULL) {
|
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
||||||
sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
|
"client sent invalid base64 encoding "
|
||||||
if (sslcf->starttls) {
|
"in AUTH CRAM-MD5 command");
|
||||||
c->read->handler = ngx_mail_starttls_handler;
|
rc = NGX_MAIL_PARSE_INVALID_COMMAND;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = s->login.data;
|
||||||
|
last = p + s->login.len;
|
||||||
|
|
||||||
|
while (p < last) {
|
||||||
|
if (*p++ == ' ') {
|
||||||
|
s->login.len = p - s->login.data - 1;
|
||||||
|
s->passwd.len = last - p;
|
||||||
|
s->passwd.data = p;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = NGX_MAIL_PARSE_INVALID_COMMAND;
|
if (s->passwd.len != 32) {
|
||||||
break;
|
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
||||||
#endif
|
"client sent invalid CRAM-MD5 hash "
|
||||||
|
"in AUTH CRAM-MD5 command");
|
||||||
|
rc = NGX_MAIL_PARSE_INVALID_COMMAND;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
ngx_log_debug2(NGX_LOG_DEBUG_MAIL, c->log, 0,
|
||||||
rc = NGX_MAIL_PARSE_INVALID_COMMAND;
|
"imap auth cram-md5: \"%V\" \"%V\"",
|
||||||
break;
|
&s->login, &s->passwd);
|
||||||
|
|
||||||
|
s->auth_method = NGX_MAIL_AUTH_CRAM_MD5;
|
||||||
|
|
||||||
|
ngx_mail_do_auth(s);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (rc == NGX_IMAP_NEXT) {
|
} else if (rc == NGX_IMAP_NEXT) {
|
||||||
@ -1171,6 +1403,8 @@ ngx_imap_auth_state(ngx_event_t *rev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rc == NGX_MAIL_PARSE_INVALID_COMMAND) {
|
if (rc == NGX_MAIL_PARSE_INVALID_COMMAND) {
|
||||||
|
s->mail_state = ngx_imap_start;
|
||||||
|
s->state = 0;
|
||||||
last = imap_invalid_command;
|
last = imap_invalid_command;
|
||||||
last_len = sizeof(imap_invalid_command) - 1;
|
last_len = sizeof(imap_invalid_command) - 1;
|
||||||
}
|
}
|
||||||
@ -1209,9 +1443,18 @@ ngx_imap_auth_state(ngx_event_t *rev)
|
|||||||
|
|
||||||
if (rc != NGX_IMAP_NEXT) {
|
if (rc != NGX_IMAP_NEXT) {
|
||||||
s->args.nelts = 0;
|
s->args.nelts = 0;
|
||||||
s->buffer->pos = s->buffer->start;
|
|
||||||
s->buffer->last = s->buffer->start;
|
if (s->state) {
|
||||||
s->tag.len = 0;
|
/* preserve tag */
|
||||||
|
s->arg_start = s->buffer->start + s->tag.len;
|
||||||
|
s->buffer->pos = s->arg_start;
|
||||||
|
s->buffer->last = s->arg_start;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
s->buffer->pos = s->buffer->start;
|
||||||
|
s->buffer->last = s->buffer->start;
|
||||||
|
s->tag.len = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_mail_send(c->write);
|
ngx_mail_send(c->write);
|
||||||
|
@ -354,6 +354,27 @@ ngx_int_t ngx_imap_parse_command(ngx_mail_session_t *s)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 12:
|
||||||
|
if ((c[0] == 'A'|| c[0] == 'a')
|
||||||
|
&& (c[1] == 'U'|| c[1] == 'u')
|
||||||
|
&& (c[2] == 'T'|| c[2] == 't')
|
||||||
|
&& (c[3] == 'H'|| c[3] == 'h')
|
||||||
|
&& (c[4] == 'E'|| c[4] == 'e')
|
||||||
|
&& (c[5] == 'N'|| c[5] == 'n')
|
||||||
|
&& (c[6] == 'T'|| c[6] == 't')
|
||||||
|
&& (c[7] == 'I'|| c[7] == 'i')
|
||||||
|
&& (c[8] == 'C'|| c[8] == 'c')
|
||||||
|
&& (c[9] == 'A'|| c[9] == 'a')
|
||||||
|
&& (c[10] == 'T'|| c[10] == 't')
|
||||||
|
&& (c[11] == 'E'|| c[11] == 'e'))
|
||||||
|
{
|
||||||
|
s->command = NGX_IMAP_AUTHENTICATE;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
goto invalid;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
goto invalid;
|
goto invalid;
|
||||||
}
|
}
|
||||||
@ -573,7 +594,7 @@ done:
|
|||||||
s->literal_len = 0;
|
s->literal_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->state = sw_start;
|
s->state = (s->command != NGX_IMAP_AUTHENTICATE) ? sw_start : sw_argument;
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user