<feed xmlns='http://www.w3.org/2005/Atom'>
<title>nginx.git/src/mail/ngx_mail_parse.c, branch release-1.30.0</title>
<subtitle>nginx</subtitle>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/'/>
<entry>
<title>Mail: fixed type overflow in IMAP literal length parser.</title>
<updated>2026-03-04T08:08:09+00:00</updated>
<author>
<name>Sergey Kandaurov</name>
<email>pluknet@nginx.com</email>
</author>
<published>2026-02-27T17:46:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=dff46cd1ae0095922e7eb9cf5b32ebe1e68a5706'/>
<id>dff46cd1ae0095922e7eb9cf5b32ebe1e68a5706</id>
<content type='text'>
The overflow is safe, because the maximum length of literals
is limited with the "imap_client_buffer" directive.

Reported by Bartłomiej Dmitruk.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The overflow is safe, because the maximum length of literals
is limited with the "imap_client_buffer" directive.

Reported by Bartłomiej Dmitruk.
</pre>
</div>
</content>
</entry>
<entry>
<title>Mail: stricter IMAP literals validation.</title>
<updated>2026-03-04T08:08:09+00:00</updated>
<author>
<name>Sergey Kandaurov</name>
<email>pluknet@nginx.com</email>
</author>
<published>2026-02-27T17:18:16+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=aa65a60fc7bcef4152152cf5a4e87f04cad54368'/>
<id>aa65a60fc7bcef4152152cf5a4e87f04cad54368</id>
<content type='text'>
As clarified in RFC 3501, Section 7.5, literals are followed
either by SP, for additional command arguments, or CRLF.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
As clarified in RFC 3501, Section 7.5, literals are followed
either by SP, for additional command arguments, or CRLF.
</pre>
</div>
</content>
</entry>
<entry>
<title>Mail: IMAP pipelining support.</title>
<updated>2021-05-19T00:13:28+00:00</updated>
<author>
<name>Maxim Dounin</name>
<email>mdounin@mdounin.ru</email>
</author>
<published>2021-05-19T00:13:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=5015209054f68141cd4f5f61e874d4497d4ef49c'/>
<id>5015209054f68141cd4f5f61e874d4497d4ef49c</id>
<content type='text'>
The change is mostly the same as the SMTP one (04e43d03e153 and 3f5d0af4e40a),
and ensures that nginx is able to properly handle or reject multiple IMAP
commands.  The s-&gt;cmd field is not really used and set for consistency.

Non-synchronizing literals handling in invalid/unknown commands is limited,
so when a non-synchronizing literal is detected at the end of a discarded
line, the connection is closed.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The change is mostly the same as the SMTP one (04e43d03e153 and 3f5d0af4e40a),
and ensures that nginx is able to properly handle or reject multiple IMAP
commands.  The s-&gt;cmd field is not really used and set for consistency.

Non-synchronizing literals handling in invalid/unknown commands is limited,
so when a non-synchronizing literal is detected at the end of a discarded
line, the connection is closed.
</pre>
</div>
</content>
</entry>
<entry>
<title>Mail: stricter checking of IMAP tags.</title>
<updated>2021-05-19T00:13:26+00:00</updated>
<author>
<name>Maxim Dounin</name>
<email>mdounin@mdounin.ru</email>
</author>
<published>2021-05-19T00:13:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=4617dd64b863df111e33b1b395709f4c2f427350'/>
<id>4617dd64b863df111e33b1b395709f4c2f427350</id>
<content type='text'>
Only "A-Za-z0-9-._" characters now allowed (which is stricter than what
RFC 3501 requires, but expected to be enough for all known clients),
and tags shouldn't be longer than 32 characters.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Only "A-Za-z0-9-._" characters now allowed (which is stricter than what
RFC 3501 requires, but expected to be enough for all known clients),
and tags shouldn't be longer than 32 characters.
</pre>
</div>
</content>
</entry>
<entry>
<title>Mail: fixed backslash handling in IMAP literals.</title>
<updated>2021-05-19T00:13:23+00:00</updated>
<author>
<name>Maxim Dounin</name>
<email>mdounin@mdounin.ru</email>
</author>
<published>2021-05-19T00:13:23+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=82840d165144584d1b288521266051a6b5a462eb'/>
<id>82840d165144584d1b288521266051a6b5a462eb</id>
<content type='text'>
Previously, s-&gt;backslash was set if any of the arguments was a quoted
string with a backslash character.  After successful command parsing
this resulted in all arguments being filtered to remove backslashes.
This is, however, incorrect, as backslashes should not be removed from
IMAP literals.  For example:

   S: * OK IMAP4 ready
   C: a01 login {9}
   S: + OK
   C: user\name "pass\"word"
   S: * BAD internal server error

resulted in "Auth-User: username" instead of "Auth-User: user\name"
as it should.

Fix is to apply backslash filtering on per-argument basis during parsing.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Previously, s-&gt;backslash was set if any of the arguments was a quoted
string with a backslash character.  After successful command parsing
this resulted in all arguments being filtered to remove backslashes.
This is, however, incorrect, as backslashes should not be removed from
IMAP literals.  For example:

   S: * OK IMAP4 ready
   C: a01 login {9}
   S: + OK
   C: user\name "pass\"word"
   S: * BAD internal server error

resulted in "Auth-User: username" instead of "Auth-User: user\name"
as it should.

Fix is to apply backslash filtering on per-argument basis during parsing.
</pre>
</div>
</content>
</entry>
<entry>
<title>Mail: removed dead s-&gt;arg_start handling.</title>
<updated>2021-05-19T00:13:22+00:00</updated>
<author>
<name>Maxim Dounin</name>
<email>mdounin@mdounin.ru</email>
</author>
<published>2021-05-19T00:13:22+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=fabe28259f4e191fee660a240ba347a0a8d2f1dc'/>
<id>fabe28259f4e191fee660a240ba347a0a8d2f1dc</id>
<content type='text'>
As discussed in the previous change, s-&gt;arg_start handling in the "done"
labels of ngx_mail_pop3_parse_command(), ngx_mail_imap_parse_command(),
and ngx_mail_smtp_parse_command() is wrong: s-&gt;arg_start cannot be
set there, as it is handled and cleared on all code paths where the
"done" labels are reached.  The relevant code is dead and now removed.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
As discussed in the previous change, s-&gt;arg_start handling in the "done"
labels of ngx_mail_pop3_parse_command(), ngx_mail_imap_parse_command(),
and ngx_mail_smtp_parse_command() is wrong: s-&gt;arg_start cannot be
set there, as it is handled and cleared on all code paths where the
"done" labels are reached.  The relevant code is dead and now removed.
</pre>
</div>
</content>
</entry>
<entry>
<title>Mail: fixed s-&gt;arg_start clearing on invalid IMAP commands.</title>
<updated>2021-05-19T00:13:20+00:00</updated>
<author>
<name>Maxim Dounin</name>
<email>mdounin@mdounin.ru</email>
</author>
<published>2021-05-19T00:13:20+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=3c660ef59b545bf76f2fb2b6a37ca02bcae4b2fb'/>
<id>3c660ef59b545bf76f2fb2b6a37ca02bcae4b2fb</id>
<content type='text'>
Previously, s-&gt;arg_start was left intact after invalid IMAP commands,
and this might result in an argument incorrectly added to the following
command.  Similarly, s-&gt;backslash was left intact as well, leading
to unneeded backslash removal.

For example (LFs from the client are explicitly shown as "&lt;LF&gt;"):

  S: * OK IMAP4 ready
  C: a01 login "\&lt;LF&gt;
  S: a01 BAD invalid command
  C: a0000000000\2 authenticate &lt;LF&gt;
  S: a00000000002 aBAD invalid command

The backslash followed by LF generates invalid command with s-&gt;arg_start
and s-&gt;backslash set, the following command incorrectly treats anything
from the old s-&gt;arg_start to the space after the command as an argument,
and removes the backslash from the tag.  If there is no space, s-&gt;arg_end
will be NULL.

Both things seem to be harmless though.  In particular:

- This can be used to provide an incorrect argument to a command without
  arguments.  The only command which seems to look at the single argument
  is AUTHENTICATE, and it checks the argument length before trying to
  access it.

- Backslash removal uses the "end" pointer, and stops due to "src &lt; end"
  condition instead of scanning all the process memory if s-&gt;arg_end is
  NULL (and arg[0].len is huge).

- There should be no backslashes in unquoted strings.

An obvious fix is to clear s-&gt;arg_start and s-&gt;backslash on invalid commands,
similarly to how it is done in POP3 parsing (added in 810:e3aa8f305d21) and
SMTP parsing.

This, however, makes it clear that s-&gt;arg_start handling in the "done"
label is wrong: s-&gt;arg_start cannot be legitimately set there, as it
is expected to be cleared in all possible cases when the "done" label is
reached.  The relevant code is dead and will be removed by the following
change.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Previously, s-&gt;arg_start was left intact after invalid IMAP commands,
and this might result in an argument incorrectly added to the following
command.  Similarly, s-&gt;backslash was left intact as well, leading
to unneeded backslash removal.

For example (LFs from the client are explicitly shown as "&lt;LF&gt;"):

  S: * OK IMAP4 ready
  C: a01 login "\&lt;LF&gt;
  S: a01 BAD invalid command
  C: a0000000000\2 authenticate &lt;LF&gt;
  S: a00000000002 aBAD invalid command

The backslash followed by LF generates invalid command with s-&gt;arg_start
and s-&gt;backslash set, the following command incorrectly treats anything
from the old s-&gt;arg_start to the space after the command as an argument,
and removes the backslash from the tag.  If there is no space, s-&gt;arg_end
will be NULL.

Both things seem to be harmless though.  In particular:

- This can be used to provide an incorrect argument to a command without
  arguments.  The only command which seems to look at the single argument
  is AUTHENTICATE, and it checks the argument length before trying to
  access it.

- Backslash removal uses the "end" pointer, and stops due to "src &lt; end"
  condition instead of scanning all the process memory if s-&gt;arg_end is
  NULL (and arg[0].len is huge).

- There should be no backslashes in unquoted strings.

An obvious fix is to clear s-&gt;arg_start and s-&gt;backslash on invalid commands,
similarly to how it is done in POP3 parsing (added in 810:e3aa8f305d21) and
SMTP parsing.

This, however, makes it clear that s-&gt;arg_start handling in the "done"
label is wrong: s-&gt;arg_start cannot be legitimately set there, as it
is expected to be cleared in all possible cases when the "done" label is
reached.  The relevant code is dead and will be removed by the following
change.
</pre>
</div>
</content>
</entry>
<entry>
<title>Mail: POP3 pipelining support.</title>
<updated>2021-05-19T00:13:18+00:00</updated>
<author>
<name>Maxim Dounin</name>
<email>mdounin@mdounin.ru</email>
</author>
<published>2021-05-19T00:13:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=d96d60d2e0a41a4e01163f7e5d1835e028f94b72'/>
<id>d96d60d2e0a41a4e01163f7e5d1835e028f94b72</id>
<content type='text'>
The change is mostly the same as the SMTP one (04e43d03e153 and 3f5d0af4e40a),
and ensures that nginx is able to properly handle or reject multiple POP3
commands, as required by the PIPELINING capability (RFC 2449).  The s-&gt;cmd
field is not really used and set for consistency.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The change is mostly the same as the SMTP one (04e43d03e153 and 3f5d0af4e40a),
and ensures that nginx is able to properly handle or reject multiple POP3
commands, as required by the PIPELINING capability (RFC 2449).  The s-&gt;cmd
field is not really used and set for consistency.
</pre>
</div>
</content>
</entry>
<entry>
<title>Mail: optimized discarding invalid SMTP commands.</title>
<updated>2021-05-19T00:13:17+00:00</updated>
<author>
<name>Maxim Dounin</name>
<email>mdounin@mdounin.ru</email>
</author>
<published>2021-05-19T00:13:17+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=317223cb56f70f3fc2eb646a78a8f0161cafa70b'/>
<id>317223cb56f70f3fc2eb646a78a8f0161cafa70b</id>
<content type='text'>
There is no need to scan buffer from s-&gt;buffer-&gt;pos, as we already scanned
the buffer till "p" and wasn't able to find an LF.

There is no real need for this change in SMTP, since it is at most a
microoptimization of a non-common code path.  Similar code in IMAP, however,
will have to start scanning from "p" to be correct, since there can be
newlines in IMAP literals.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
There is no need to scan buffer from s-&gt;buffer-&gt;pos, as we already scanned
the buffer till "p" and wasn't able to find an LF.

There is no real need for this change in SMTP, since it is at most a
microoptimization of a non-common code path.  Similar code in IMAP, however,
will have to start scanning from "p" to be correct, since there can be
newlines in IMAP literals.
</pre>
</div>
</content>
</entry>
<entry>
<title>Mail: fixed handling of invalid SMTP commands split between reads.</title>
<updated>2021-05-19T00:13:15+00:00</updated>
<author>
<name>Maxim Dounin</name>
<email>mdounin@mdounin.ru</email>
</author>
<published>2021-05-19T00:13:15+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/nginx.git/commit/?id=204f944add09c43223de317451175d5fdb7d1fb0'/>
<id>204f944add09c43223de317451175d5fdb7d1fb0</id>
<content type='text'>
Previously, if an invalid SMTP command was split between reads, nginx failed
to wait for LF before returning an error, and interpreted the rest of the
command received later as a separate command.

The sw_invalid state in ngx_mail_smtp_parse_command(), introduced in
04e43d03e153, did not work, since ngx_mail_smtp_auth_state() clears
s-&gt;state when returning an error due to NGX_MAIL_PARSE_INVALID_COMMAND.
And not clearing s-&gt;state will introduce another problem: the rest
of the command would trigger duplicate error when rest of the command is
received.

Fix is to return NGX_AGAIN from ngx_mail_smtp_parse_command() until full
command is received.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Previously, if an invalid SMTP command was split between reads, nginx failed
to wait for LF before returning an error, and interpreted the rest of the
command received later as a separate command.

The sw_invalid state in ngx_mail_smtp_parse_command(), introduced in
04e43d03e153, did not work, since ngx_mail_smtp_auth_state() clears
s-&gt;state when returning an error due to NGX_MAIL_PARSE_INVALID_COMMAND.
And not clearing s-&gt;state will introduce another problem: the rest
of the command would trigger duplicate error when rest of the command is
received.

Fix is to return NGX_AGAIN from ngx_mail_smtp_parse_command() until full
command is received.
</pre>
</div>
</content>
</entry>
</feed>
