-
Notifications
You must be signed in to change notification settings - Fork 7.3k
Mail: handling of CAPABILITY in the LOGIN IMAP command. #276
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
src/mail/ngx_mail_proxy_module.c
Outdated
@@ -1019,12 +1019,39 @@ ngx_mail_proxy_read_response(ngx_mail_session_t *s, ngx_uint_t state) | |||
break; | |||
|
|||
case ngx_imap_passwd: | |||
|
|||
if (ngx_strncmp(p, s->tag.data, s->tag.len) != 0) { | |||
/* as per RFC 3501, 6.2.3 LOGIN Command */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a newer RFC 9051 which obsoletes RFC 3501.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, Section 6.2.3 of the RFC says nothing about the untagged CAPABILITY response. It says that CAPABILITY response code MAY be included in the tagged OK response. Something like this:
S: tag1 OK [CAPABILITY IMAP4rev2 STARTTLS AUTH=GSSAPI]
Reading the RFC, I only see one command CAPABILITY
that's allowed to return the untagged response. Other commands may return CAPABILITY only inside a tagged response.
Having said that, I do see IMAP logs which indicate some servers actually do that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a newer RFC 9051 which obsoletes RFC 3501.
RFC 9051 describes IMAP4rev2. While it is intended to be upwards compatible from the IMAP4rev1, this is a different protocol.
In particular, from RFC 3501, 7.2.1:
Client implementations SHOULD NOT require any capability name
other than "IMAP4rev1", and MUST ignore any unknown capability
names.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, Section 6.2.3 of the RFC says nothing about the untagged CAPABILITY response.
That's true. It said this in interim internet drafts before the final version, so referring to RFC 3501 (nor 9051) is not actually correct.
Still there are implementations in the wild, that use untagged CAPABILITY response.
Such are SmarterMail and GMail, see for example: https://civicrm.stackexchange.com/questions/34584/imap-authentication-error-with-smartermail and https://alioth-lists.debian.net/pipermail/offlineimap-project/2011-June/009349.html
|
Removed outer condition. |
In particular, an untagged CAPABILITY response as described in the interim RFC 3501 internet drafts was seen in various IMAP servers. Previously resulted in a broken connection, now an untagged response is proxied to client.
Addressed comments, fixed commit log. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The patch is ok, but I don't see a quick way to test it properly. Adding the untagged response to our test imap server ends up with errors since it's unexpected for the test.
It can be tested with this patch for nginx-tests. diff --git a/lib/Test/Nginx/IMAP.pm b/lib/Test/Nginx/IMAP.pm
index d172ec3..86dd27f 100644
--- a/lib/Test/Nginx/IMAP.pm
+++ b/lib/Test/Nginx/IMAP.pm
@@ -178,6 +178,10 @@ sub imap_test_daemon {
if (/^logout/i) {
print $client $tag . ' OK logout ok' . CRLF;
+ } elsif (/^login \{15\}/i) {
+ print $client
+ "* CAPABILITY IMAP4rev1 AUTH=PLAIN". CRLF;
+ print $client $tag . ' OK login ok' . CRLF;
} elsif (/^login /i) {
print $client $tag . ' OK login ok' . CRLF;
} else {
diff --git a/mail_imap.t b/mail_imap.t
index 5ad4983..e8e7216 100644
--- a/mail_imap.t
+++ b/mail_imap.t
@@ -38,7 +38,7 @@ events {
}
mail {
- proxy_pass_error_message on;
+ proxy_pass_error_message off;
proxy_timeout 15s;
auth_http http://127.0.0.1:8080/mail/auth;
@@ -80,6 +80,11 @@ http {
set $passw secret;
}
+ set $userpass "$http_auth_user:$http_auth_pass";
+ if ($userpass = '[email protected]:secret') {
+ set $reply OK;
+ }
+
add_header Auth-Status $reply;
add_header Auth-Server 127.0.0.1;
add_header Auth-Port %%PORT_8144%%;
@@ -93,7 +98,7 @@ http {
EOF
$t->run_daemon(\&Test::Nginx::IMAP::imap_test_daemon);
-$t->run()->plan(29);
+$t->run()->plan(31);
$t->waitforsocket('127.0.0.1:' . port(8144));
@@ -113,6 +118,15 @@ $s->check(qr/^a02 NO/, 'login with bad password');
$s->send('a03 LOGIN [email protected] secret');
$s->ok('login');
+# login with untagged capability
+
+$s = Test::Nginx::IMAP->new();
+$s->read();
+
+$s->send('a04 LOGIN [email protected] secret');
+$s->check(qr/\Q* CAPABILITY \E/, 'untagged capability');
+$s->ok('login after capability');
+
# auth
$s = Test::Nginx::IMAP->new(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
SmarterMail IMAP server may send an optional untagged CAPABILITY response.
Previously resulted in a broken connection, now it is passed.