[PATCH 1 of 7] Mail: add IMAP ID command support
Filipe da Silva
fdasilvayy at gmail.com
Tue Jan 14 11:54:18 UTC 2014
# HG changeset patch
# User Filipe da Silva <fdasilvayy at gmail.com>
# Date 1389700210 -3600
# Tue Jan 14 12:50:10 2014 +0100
# Node ID 0ff28c3c519125db11ae3c56fbf34a7a5975a452
# Parent d049b0ea00a388c142627f10a0ee01c5b1bedc43
Mail: add IMAP ID command support.
add parsing of IMAP ID command and his parameter list, see RFC2971
diff -r d049b0ea00a3 -r 0ff28c3c5191 src/mail/ngx_mail.h
--- a/src/mail/ngx_mail.h Fri Jan 10 16:12:40 2014 +0100
+++ b/src/mail/ngx_mail.h Tue Jan 14 12:50:10 2014 +0100
@@ -215,6 +215,7 @@
unsigned quoted:1;
unsigned backslash:1;
unsigned no_sync_literal:1;
+ unsigned params_list:1;
unsigned starttls:1;
unsigned esmtp:1;
unsigned auth_method:3;
@@ -233,6 +234,7 @@
ngx_str_t smtp_helo;
ngx_str_t smtp_from;
ngx_str_t smtp_to;
+ ngx_str_t imap_client_id;
ngx_str_t cmd;
@@ -284,6 +286,7 @@
#define NGX_IMAP_AUTHENTICATE 7
+#define NGX_IMAP_ID 8
#define NGX_SMTP_HELO 1
#define NGX_SMTP_EHLO 2
diff -r d049b0ea00a3 -r 0ff28c3c5191 src/mail/ngx_mail_imap_handler.c
--- a/src/mail/ngx_mail_imap_handler.c Fri Jan 10 16:12:40 2014 +0100
+++ b/src/mail/ngx_mail_imap_handler.c Tue Jan 14 12:50:10 2014 +0100
@@ -16,6 +16,8 @@
ngx_connection_t *c);
static ngx_int_t ngx_mail_imap_authenticate(ngx_mail_session_t *s,
ngx_connection_t *c);
+static ngx_int_t ngx_mail_imap_id(ngx_mail_session_t *s,
+ ngx_connection_t *c);
static ngx_int_t ngx_mail_imap_capability(ngx_mail_session_t *s,
ngx_connection_t *c);
static ngx_int_t ngx_mail_imap_starttls(ngx_mail_session_t *s,
@@ -32,6 +34,9 @@
static u_char imap_bye[] = "* BYE" CRLF;
static u_char imap_invalid_command[] = "BAD invalid command" CRLF;
+static ngx_str_t ngx_mail_imap_client_id_nil = ngx_string("ID NIL");
+static ngx_str_t ngx_mail_imap_server_id_nil = ngx_string("* ID NIL" CRLF);
+
void
ngx_mail_imap_init_session(ngx_mail_session_t *s, ngx_connection_t *c)
@@ -179,6 +184,10 @@
tag = (rc != NGX_OK);
break;
+ case NGX_IMAP_ID:
+ rc = ngx_mail_imap_id(s, c);
+ break;
+
case NGX_IMAP_CAPABILITY:
rc = ngx_mail_imap_capability(s, c);
break;
@@ -292,6 +301,60 @@
ngx_mail_send(c->write);
}
+static ngx_int_t
+ngx_mail_imap_id(ngx_mail_session_t *s, ngx_connection_t *c)
+{
+ ngx_str_t *arg;
+ size_t size, i;
+ u_char *p, *data;
+
+ arg = s->args.elts;
+ if (s->args.nelts < 1 || arg[0].len == 0) {
+ return NGX_MAIL_PARSE_INVALID_COMMAND;
+ }
+
+ // Client sends ID NIL or ID ( ... )
+ if (s->args.nelts == 1) {
+
+ if (ngx_strncasecmp(arg[0].data, (u_char *) "NIL", 3) != 0)
+ return NGX_MAIL_PARSE_INVALID_COMMAND;
+
+ s->imap_client_id = ngx_mail_imap_client_id_nil;
+
+ } else {
+ size = sizeof("ID (") - 1;
+ for (i = 0; i < s->args.nelts; i++) {
+ size += 1 + arg[i].len + 2; // 1 space plus 2 quotes
+ }
+
+ data = ngx_pnalloc(c->pool, size);
+ if (data == NULL) {
+ return NGX_ERROR;
+ }
+
+ p = ngx_cpymem(data, "ID (", sizeof("ID (") - 1);
+ for (i = 0; i < s->args.nelts; i++) {
+ *p++ = '"';
+ p = ngx_cpymem(p, arg[i].data, arg[i].len);
+ *p++ = '"';
+ *p++ = ' ';
+ }
+ *--p = ')'; // replace last space
+
+ s->imap_client_id.len = size;
+ s->imap_client_id.data = data;
+ }
+
+ ngx_log_debug2(NGX_LOG_DEBUG_MAIL, c->log, 0,
+ "imap client ID:\"%V%V\"",
+ &s->tag, &s->imap_client_id);
+
+ // Prepare server response to ID command
+ s->text = ngx_mail_imap_server_id_nil;
+
+ return NGX_OK;
+}
+
static ngx_int_t
ngx_mail_imap_login(ngx_mail_session_t *s, ngx_connection_t *c)
diff -r d049b0ea00a3 -r 0ff28c3c5191 src/mail/ngx_mail_parse.c
--- a/src/mail/ngx_mail_parse.c Fri Jan 10 16:12:40 2014 +0100
+++ b/src/mail/ngx_mail_parse.c Tue Jan 14 12:50:10 2014 +0100
@@ -279,6 +279,16 @@
c = s->cmd_start;
switch (p - c) {
+ case 2:
+ if ((c[0] == 'I' || c[0] == 'i')
+ && (c[1] == 'D'|| c[1] == 'd'))
+ {
+ s->command = NGX_IMAP_ID;
+
+ } else {
+ goto invalid;
+ }
+ break;
case 4:
if ((c[0] == 'N' || c[0] == 'n')
@@ -409,14 +419,31 @@
case ' ':
break;
case CR:
+ if (s->params_list == 1)
+ goto invalid;
state = sw_almost_done;
s->arg_end = p;
break;
case LF:
+ if (s->params_list == 1)
+ goto invalid;
s->arg_end = p;
goto done;
+ case '(': // params list begin
+ if (!s->params_list && s->args.nelts == 0) {
+ s->params_list = 1;
+ break;
+ }
+ goto invalid;
+ case ')': // params list closing
+ if (s->params_list == 1 && s->args.nelts > 0) {
+ s->params_list = 0;
+ state = sw_spaces_before_argument;
+ break;
+ }
+ goto invalid;
case '"':
- if (s->args.nelts <= 2) {
+ if (s->args.nelts <= 2 || s->params_list) {
s->quoted = 1;
s->arg_start = p + 1;
state = sw_argument;
@@ -430,7 +457,7 @@
}
goto invalid;
default:
- if (s->args.nelts <= 2) {
+ if (s->args.nelts <= 2 && !s->params_list) {
s->arg_start = p;
state = sw_argument;
break;
@@ -602,6 +629,7 @@
s->quoted = 0;
s->no_sync_literal = 0;
s->literal_len = 0;
+ s->params_list = 0;
}
s->state = (s->command != NGX_IMAP_AUTHENTICATE) ? sw_start : sw_argument;
@@ -614,6 +642,7 @@
s->quoted = 0;
s->no_sync_literal = 0;
s->literal_len = 0;
+ s->params_list = 0;
return NGX_MAIL_PARSE_INVALID_COMMAND;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 000-ImapID_CommandSupport.diff
Type: text/x-patch
Size: 6682 bytes
Desc: not available
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20140114/05be87e2/attachment-0001.bin>
More information about the nginx-devel
mailing list