optimizations
diff --git a/src/mail/ngx_mail.h b/src/mail/ngx_mail.h
index d282d9f..1d81e35 100644
--- a/src/mail/ngx_mail.h
+++ b/src/mail/ngx_mail.h
@@ -313,6 +313,7 @@
#if (NGX_MAIL_SSL)
void ngx_mail_starttls_handler(ngx_event_t *rev);
+ngx_int_t ngx_mail_starttls_only(ngx_mail_session_t *s, ngx_connection_t *c);
#endif
@@ -330,6 +331,8 @@
ngx_connection_t *c);
ngx_int_t ngx_mail_auth_login_password(ngx_mail_session_t *s,
ngx_connection_t *c);
+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);
void ngx_mail_send(ngx_event_t *wev);
@@ -351,6 +354,7 @@
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);
/* STUB */
diff --git a/src/mail/ngx_mail_handler.c b/src/mail/ngx_mail_handler.c
index 251d316..8f549a8 100644
--- a/src/mail/ngx_mail_handler.c
+++ b/src/mail/ngx_mail_handler.c
@@ -285,6 +285,29 @@
}
+#if (NGX_MAIL_SSL)
+
+ngx_int_t
+ngx_mail_starttls_only(ngx_mail_session_t *s, ngx_connection_t *c)
+{
+ ngx_mail_ssl_conf_t *sslcf;
+
+ if (c->ssl) {
+ return 0;
+ }
+
+ sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
+
+ if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
+ return 1;
+ }
+
+ return 0;
+}
+
+#endif
+
+
ngx_int_t
ngx_mail_auth_plain(ngx_mail_session_t *s, ngx_connection_t *c, ngx_uint_t n)
{
@@ -405,6 +428,35 @@
ngx_int_t
+ngx_mail_auth_cram_md5_salt(ngx_mail_session_t *s, ngx_connection_t *c,
+ char *prefix, size_t len)
+{
+ u_char *p;
+ ngx_str_t salt;
+ ngx_uint_t n;
+
+ p = ngx_palloc(c->pool, len + ngx_base64_encoded_length(s->salt.len) + 2);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
+
+ salt.data = ngx_cpymem(p, prefix, len);
+ s->salt.len -= 2;
+
+ ngx_encode_base64(&salt, &s->salt);
+
+ s->salt.len += 2;
+ n = len + salt.len;
+ p[n++] = CR; p[n++] = LF;
+
+ s->out.len = n;
+ s->out.data = p;
+
+ return NGX_OK;
+}
+
+
+ngx_int_t
ngx_mail_auth_cram_md5(ngx_mail_session_t *s, ngx_connection_t *c)
{
u_char *p, *last;
diff --git a/src/mail/ngx_mail_imap_handler.c b/src/mail/ngx_mail_imap_handler.c
index 71ccb57..47a79c6 100644
--- a/src/mail/ngx_mail_imap_handler.c
+++ b/src/mail/ngx_mail_imap_handler.c
@@ -177,11 +177,7 @@
case NGX_IMAP_AUTHENTICATE:
rc = ngx_mail_imap_authenticate(s, c);
-
- if (rc == NGX_OK) {
- tag = 0;
- }
-
+ tag = (rc != NGX_OK);
break;
case NGX_IMAP_CAPABILITY:
@@ -307,15 +303,10 @@
ngx_mail_imap_login(ngx_mail_session_t *s, ngx_connection_t *c)
{
ngx_str_t *arg;
+
#if (NGX_MAIL_SSL)
- ngx_mail_ssl_conf_t *sslcf;
-
- if (c->ssl == NULL) {
- sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
-
- if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
+ if (ngx_mail_starttls_only(s, c)) {
+ return NGX_MAIL_PARSE_INVALID_COMMAND;
}
#endif
@@ -357,53 +348,36 @@
static ngx_int_t
ngx_mail_imap_authenticate(ngx_mail_session_t *s, ngx_connection_t *c)
{
- u_char *p;
- ngx_str_t *arg, salt;
- ngx_uint_t n;
+ ngx_int_t rc;
ngx_mail_core_srv_conf_t *cscf;
+
#if (NGX_MAIL_SSL)
- ngx_mail_ssl_conf_t *sslcf;
-
- if (c->ssl == NULL) {
- sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
-
- if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
+ if (ngx_mail_starttls_only(s, c)) {
+ return NGX_MAIL_PARSE_INVALID_COMMAND;
}
#endif
- if (s->args.nelts != 1) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
+ rc = ngx_mail_auth_parse(s, c);
- arg = s->args.elts;
+ switch (rc) {
- if (arg[0].len == 5) {
+ case NGX_MAIL_AUTH_LOGIN:
- if (ngx_strncasecmp(arg[0].data, (u_char *) "LOGIN", 5) == 0) {
+ s->out.len = sizeof(imap_username) - 1;
+ s->out.data = imap_username;
+ s->mail_state = ngx_imap_auth_login_username;
- s->out.len = sizeof(imap_username) - 1;
- s->out.data = imap_username;
- s->mail_state = ngx_imap_auth_login_username;
+ return NGX_OK;
- return NGX_OK;
+ case NGX_MAIL_AUTH_PLAIN:
- } else if (ngx_strncasecmp(arg[0].data, (u_char *) "PLAIN", 5) == 0) {
+ s->out.len = sizeof(imap_plain_next) - 1;
+ s->out.data = imap_plain_next;
+ s->mail_state = ngx_imap_auth_plain;
- s->out.len = sizeof(imap_plain_next) - 1;
- s->out.data = imap_plain_next;
- s->mail_state = ngx_imap_auth_plain;
+ return NGX_OK;
- return NGX_OK;
- }
-
- } else if (arg[0].len == 8
- && ngx_strncasecmp(arg[0].data, (u_char *) "CRAM-MD5", 8) == 0)
- {
- if (s->args.nelts != 1) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
+ case NGX_MAIL_AUTH_CRAM_MD5:
cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
@@ -411,31 +385,15 @@
return NGX_MAIL_PARSE_INVALID_COMMAND;
}
- p = ngx_palloc(c->pool,
- sizeof("+ " CRLF) - 1
- + ngx_base64_encoded_length(s->salt.len));
- if (p == NULL) {
- return NGX_ERROR;
+ if (ngx_mail_auth_cram_md5_salt(s, c, "+ ", 2) == NGX_OK) {
+ s->mail_state = ngx_imap_auth_cram_md5;
+ return NGX_OK;
}
- p[0] = '+'; p[1]= ' ';
- salt.data = &p[2];
- s->salt.len -= 2;
-
- ngx_encode_base64(&salt, &s->salt);
-
- s->salt.len += 2;
- n = 2 + salt.len;
- p[n++] = CR; p[n++] = LF;
-
- s->out.len = n;
- s->out.data = p;
- s->mail_state = ngx_imap_auth_cram_md5;
-
- return NGX_OK;
+ return NGX_ERROR;
}
- return NGX_MAIL_PARSE_INVALID_COMMAND;
+ return rc;
}
diff --git a/src/mail/ngx_mail_parse.c b/src/mail/ngx_mail_parse.c
index d282a55..e558d2f 100644
--- a/src/mail/ngx_mail_parse.c
+++ b/src/mail/ngx_mail_parse.c
@@ -825,3 +825,56 @@
return NGX_MAIL_PARSE_INVALID_COMMAND;
}
+
+
+ngx_int_t
+ngx_mail_auth_parse(ngx_mail_session_t *s, ngx_connection_t *c)
+{
+ ngx_str_t *arg;
+
+#if (NGX_MAIL_SSL)
+ if (ngx_mail_starttls_only(s, c)) {
+ return NGX_MAIL_PARSE_INVALID_COMMAND;
+ }
+#endif
+
+ arg = s->args.elts;
+
+ if (arg[0].len == 5) {
+
+ if (ngx_strncasecmp(arg[0].data, (u_char *) "LOGIN", 5) == 0) {
+
+ if (s->args.nelts == 1) {
+ return NGX_MAIL_AUTH_LOGIN;
+ }
+
+ return NGX_MAIL_PARSE_INVALID_COMMAND;
+ }
+
+ if (ngx_strncasecmp(arg[0].data, (u_char *) "PLAIN", 5) == 0) {
+
+ if (s->args.nelts == 1) {
+ return NGX_MAIL_AUTH_PLAIN;
+ }
+
+ if (s->args.nelts == 2) {
+ return ngx_mail_auth_plain(s, c, 1);
+ }
+ }
+
+ return NGX_MAIL_PARSE_INVALID_COMMAND;
+ }
+
+ if (arg[0].len == 8) {
+
+ if (s->args.nelts != 1) {
+ return NGX_MAIL_PARSE_INVALID_COMMAND;
+ }
+
+ if (ngx_strncasecmp(arg[0].data, (u_char *) "CRAM-MD5", 8) == 0) {
+ return NGX_MAIL_AUTH_CRAM_MD5;
+ }
+ }
+
+ return NGX_MAIL_PARSE_INVALID_COMMAND;
+}
diff --git a/src/mail/ngx_mail_pop3_handler.c b/src/mail/ngx_mail_pop3_handler.c
index 734f7d2..7087871 100644
--- a/src/mail/ngx_mail_pop3_handler.c
+++ b/src/mail/ngx_mail_pop3_handler.c
@@ -275,17 +275,11 @@
ngx_mail_pop3_user(ngx_mail_session_t *s, ngx_connection_t *c)
{
ngx_str_t *arg;
+
#if (NGX_MAIL_SSL)
- ngx_mail_ssl_conf_t *sslcf;
-
- if (c->ssl == NULL) {
- sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
-
- if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
+ if (ngx_mail_starttls_only(s, c)) {
+ return NGX_MAIL_PARSE_INVALID_COMMAND;
}
-
#endif
if (s->args.nelts != 1) {
@@ -395,17 +389,11 @@
{
ngx_str_t *arg;
ngx_mail_core_srv_conf_t *cscf;
+
#if (NGX_MAIL_SSL)
- ngx_mail_ssl_conf_t *sslcf;
-
- if (c->ssl == NULL) {
- sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
-
- if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
+ if (ngx_mail_starttls_only(s, c)) {
+ return NGX_MAIL_PARSE_INVALID_COMMAND;
}
-
#endif
if (s->args.nelts != 2) {
@@ -448,21 +436,13 @@
static ngx_int_t
ngx_mail_pop3_auth(ngx_mail_session_t *s, ngx_connection_t *c)
{
- size_t n;
- u_char *p;
- ngx_str_t *arg, salt;
+ ngx_int_t rc;
ngx_mail_core_srv_conf_t *cscf;
+
#if (NGX_MAIL_SSL)
- ngx_mail_ssl_conf_t *sslcf;
-
- if (c->ssl == NULL) {
- sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
-
- if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
+ if (ngx_mail_starttls_only(s, c)) {
+ return NGX_MAIL_PARSE_INVALID_COMMAND;
}
-
#endif
cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
@@ -474,80 +454,39 @@
return NGX_OK;
}
- arg = s->args.elts;
+ rc = ngx_mail_auth_parse(s, c);
- if (arg[0].len == 5) {
+ switch (rc) {
- if (ngx_strncasecmp(arg[0].data, (u_char *) "LOGIN", 5) == 0) {
+ case NGX_MAIL_AUTH_LOGIN:
- if (s->args.nelts != 1) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
+ s->out.len = sizeof(pop3_username) - 1;
+ s->out.data = pop3_username;
+ s->mail_state = ngx_pop3_auth_login_username;
- s->out.len = sizeof(pop3_username) - 1;
- s->out.data = pop3_username;
- s->mail_state = ngx_pop3_auth_login_username;
+ return NGX_OK;
- return NGX_OK;
+ case NGX_MAIL_AUTH_PLAIN:
- } else if (ngx_strncasecmp(arg[0].data, (u_char *) "PLAIN", 5) == 0) {
+ s->out.len = sizeof(pop3_next) - 1;
+ s->out.data = pop3_next;
+ s->mail_state = ngx_pop3_auth_plain;
- if (s->args.nelts == 1) {
+ return NGX_OK;
- s->out.len = sizeof(pop3_next) - 1;
- s->out.data = pop3_next;
- s->mail_state = ngx_pop3_auth_plain;
-
- return NGX_OK;
- }
-
- if (s->args.nelts == 2) {
-
- /*
- * workaround for Eudora for Mac: it sends
- * AUTH PLAIN [base64 encoded]
- */
-
- return ngx_mail_auth_plain(s, c, 1);
- }
-
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
-
- } else if (arg[0].len == 8
- && ngx_strncasecmp(arg[0].data, (u_char *) "CRAM-MD5", 8) == 0)
- {
- if (s->args.nelts != 1) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
+ case NGX_MAIL_AUTH_CRAM_MD5:
if (!(cscf->pop3_auth_methods & NGX_MAIL_AUTH_CRAM_MD5_ENABLED)) {
return NGX_MAIL_PARSE_INVALID_COMMAND;
}
- p = ngx_palloc(c->pool,
- sizeof("+ " CRLF) - 1
- + ngx_base64_encoded_length(s->salt.len));
- if (p == NULL) {
- return NGX_ERROR;
+ if (ngx_mail_auth_cram_md5_salt(s, c, "+ ", 2) == NGX_OK) {
+ s->mail_state = ngx_pop3_auth_cram_md5;
+ return NGX_OK;
}
- p[0] = '+'; p[1]= ' ';
- salt.data = &p[2];
- s->salt.len -= 2;
-
- ngx_encode_base64(&salt, &s->salt);
-
- s->salt.len += 2;
- n = 2 + salt.len;
- p[n++] = CR; p[n++] = LF;
-
- s->out.len = n;
- s->out.data = p;
- s->mail_state = ngx_pop3_auth_cram_md5;
-
- return NGX_OK;
+ return NGX_ERROR;
}
- return NGX_MAIL_PARSE_INVALID_COMMAND;
+ return rc;
}
diff --git a/src/mail/ngx_mail_smtp_handler.c b/src/mail/ngx_mail_smtp_handler.c
index c8bcc25..76637f9 100644
--- a/src/mail/ngx_mail_smtp_handler.c
+++ b/src/mail/ngx_mail_smtp_handler.c
@@ -284,21 +284,13 @@
static ngx_int_t
ngx_mail_smtp_auth(ngx_mail_session_t *s, ngx_connection_t *c)
{
- u_char *p;
- ngx_str_t *arg, salt;
- ngx_uint_t n;
+ ngx_int_t rc;
ngx_mail_core_srv_conf_t *cscf;
+
#if (NGX_MAIL_SSL)
- ngx_mail_ssl_conf_t *sslcf;
-
- if (c->ssl == NULL) {
- sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
-
- if (sslcf->starttls == NGX_MAIL_STARTTLS_ONLY) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
+ if (ngx_mail_starttls_only(s, c)) {
+ return NGX_MAIL_PARSE_INVALID_COMMAND;
}
-
#endif
if (s->args.nelts == 0) {
@@ -308,41 +300,27 @@
return NGX_OK;
}
- if (s->args.nelts != 1) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
+ rc = ngx_mail_auth_parse(s, c);
- arg = s->args.elts;
+ switch (rc) {
- if (arg[0].len == 5) {
+ case NGX_MAIL_AUTH_LOGIN:
- if (ngx_strncasecmp(arg[0].data, (u_char *) "LOGIN", 5) == 0) {
+ s->out.len = sizeof(smtp_username) - 1;
+ s->out.data = smtp_username;
+ s->mail_state = ngx_smtp_auth_login_username;
- if (s->args.nelts != 1) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
+ return NGX_OK;
- s->out.len = sizeof(smtp_username) - 1;
- s->out.data = smtp_username;
- s->mail_state = ngx_smtp_auth_login_username;
+ case NGX_MAIL_AUTH_PLAIN:
- return NGX_OK;
+ s->out.len = sizeof(smtp_next) - 1;
+ s->out.data = smtp_next;
+ s->mail_state = ngx_smtp_auth_plain;
- } else if (ngx_strncasecmp(arg[0].data, (u_char *) "PLAIN", 5) == 0) {
+ return NGX_OK;
- s->out.len = sizeof(smtp_next) - 1;
- s->out.data = smtp_next;
- s->mail_state = ngx_smtp_auth_plain;
-
- return NGX_OK;
- }
-
- } else if (arg[0].len == 8
- && ngx_strncasecmp(arg[0].data, (u_char *) "CRAM-MD5", 8) == 0)
- {
- if (s->args.nelts != 1) {
- return NGX_MAIL_PARSE_INVALID_COMMAND;
- }
+ case NGX_MAIL_AUTH_CRAM_MD5:
cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
@@ -350,31 +328,15 @@
return NGX_MAIL_PARSE_INVALID_COMMAND;
}
- p = ngx_palloc(c->pool,
- sizeof("334 " CRLF) - 1
- + ngx_base64_encoded_length(s->salt.len));
- if (p == NULL) {
- return NGX_ERROR;
+ if (ngx_mail_auth_cram_md5_salt(s, c, "334 ", 4) == NGX_OK) {
+ s->mail_state = ngx_smtp_auth_cram_md5;
+ return NGX_OK;
}
- p[0] = '3'; p[1]= '3'; p[2] = '4'; p[3]= ' ';
- salt.data = &p[4];
- s->salt.len -= 2;
-
- ngx_encode_base64(&salt, &s->salt);
-
- s->salt.len += 2;
- n = 4 + salt.len;
- p[n++] = CR; p[n++] = LF;
-
- s->out.len = n;
- s->out.data = p;
- s->mail_state = ngx_smtp_auth_cram_md5;
-
- return NGX_OK;
+ return NGX_ERROR;
}
- return NGX_MAIL_PARSE_INVALID_COMMAND;
+ return rc;
}