Stephan Bosch [Wed, 27 Dec 2017 16:02:12 +0000 (17:02 +0100)]
lib-smtp: server: Add APIs for halting and resuming connection command handling.
Also adds function to start the connection in a pending (halted) state. This way the greeting can already be sent (over SSL if needed), while deferring command handling until some external activity is completed.
Timo Sirainen [Thu, 28 Dec 2017 12:10:23 +0000 (14:10 +0200)]
dsync: Add per-mailbox sync lock that is always used.
Both importing and exporting gets the lock before they even sync the
mailbox. The lock is kept until the import/export finishes. This guarantees
that no matter how dsync is run, two dsyncs can't be working on the same
mailbox at the same time.
This lock is in addition to the optional per-user lock enabled by the -l
parameter. If the -l parameter is used, the same lock timeout is used for
the per-mailbox lock. Otherwise 30s timeout is used.
This should help to avoid email duplication when replication is enabled for
public namespaces, and maybe in some other rare situations as well.
Timo Sirainen [Mon, 25 Dec 2017 09:10:19 +0000 (11:10 +0200)]
imapc: Add imapc_features=no-msn-updates
This is a stricter version of fetch-msn-workarounds. The MSNs aren't trusted
at all. This means any new untagged EXISTS and EXPUNGE replies are ignored,
as well as untagged FETCH replies that don't include UID.
A potential downside with this feature is that UID FETCH/STORE commands
sent to expunged messages will likely fail without the IMAP client being
notified of the EXPUNGEs. New mails are also not noticed, so this should
be used only when it's known that the clients don't keep the connection
open for long.
Timo Sirainen [Mon, 25 Dec 2017 16:24:35 +0000 (18:24 +0200)]
lib-storage: mail_storage_set_index_error() - handle NULL index error
This avoids assert-crashing later on in mail*_get_last_internal_error().
This could potentially be an assert instead of setting it as "BUG", but
it looks like there are various code paths in lib-index that return -1
without setting an error. (That's to avoid duplicate error logging,
although it could now be fixed with mail_index_set_error_nolog().)
Timo Sirainen [Mon, 25 Dec 2017 16:18:14 +0000 (18:18 +0200)]
lib-storage: Set index error on transaction commit() callback
The commit callback is setting errors to storage. However, it's being
called from mail_index_transaction_commit() whose callers are expecting
the error to be in index. If that index error was attempted to be used,
it could have been wrong or NULL. Fix this by setting the same storage
error also to the index.
Stephan Bosch [Sun, 24 Dec 2017 14:12:36 +0000 (15:12 +0100)]
submission: Restructure handling of QUIT command.
- Avoid explicitly proxying QUIT command when the proxy connection is not ready: in that case the SMTP client connection will just send QUIT if appropriate, without waiting for reply.
- Add timeout for proxied QUIT command, so that there are no problems when the relay server hangs after QUIT (addresses FIXME).
Stephan Bosch [Sun, 24 Dec 2017 11:15:29 +0000 (12:15 +0100)]
submission: Initialize proxy connection before starting the SMTP server connection.
The smtp_server_connection_login() function gets pre-login connection data from login service, which can contain commands.
The execution of commands expects the proxy connection object to be initialized.
Stephan Bosch [Sun, 24 Dec 2017 13:35:15 +0000 (14:35 +0100)]
lib-smtp: client: Fix rawlog input stream inconsistency by updating streams right after initializing TLS.
Restructured the code to call a new function called smtp_client_connection_streams_changed() which performs all the necessary updates.
Before, enabling rawlog could break the TLS handshake.
Stephan Bosch [Sat, 23 Dec 2017 21:49:57 +0000 (22:49 +0100)]
lib-smtp: client: Fix smtp_client_command_name_equals() to work properly after the command is submitted.
At command submission, CRLF is appended to command data. This messed up the name comparison.
This in turn caused a spurious QUIT command to be sent to the server at connection close.
Stephan Bosch [Sat, 23 Dec 2017 21:14:16 +0000 (22:14 +0100)]
lib-smtp: client: Make smtp_client_connection_commands_abort() more reliable by copying the command lists.
Copy the current lists of queued and waiting commands and reference each command before calling smtp_client_command_abort().
Aborting one command can cause other dependent commands to be aborted (in a transaction or from submission service), which could have caused trouble in this function.
Stephan Bosch [Sat, 23 Dec 2017 21:04:13 +0000 (22:04 +0100)]
lib-smtp: client: Make smtp_client_connection_commands_fail_reply() more reliable by copying the command lists.
Copy the current lists of queued and waiting commands and reference each command before calling smtp_client_command_fail_reply().
Failing one command can cause other dependent commands to be aborted (in a transaction or from submission service), which could have caused trouble in this function.
Problems would likely occur at connection disconnect.
Timo Sirainen [Fri, 22 Dec 2017 11:27:48 +0000 (13:27 +0200)]
lib-master: Hide connect(stats-writer) errors when running via CLI
Only hide errors that occur if the stats process isn't running, i.e. when
socket isn't found or there's no listener. This way e.g. permission errors
are still logged, which points to a wrong configuration.
Stephan Bosch [Thu, 21 Dec 2017 22:09:13 +0000 (23:09 +0100)]
lib-smtp: server: STARTTLS command: Call smtp_server_connection_set_ssl_streams() after calling the conn_start_tls() connection callback.
This is called instead smtp_server_connection_set_streams(), so that the connection is now marked as SSL-secured.
This fixes a submission-login bug that prevented client login when ssl=required.
Stephan Bosch [Mon, 18 Dec 2017 15:45:23 +0000 (16:45 +0100)]
lib-smtp: server: Fixed assertion in smtp_server_connection_next_reply() checking whether command is fully replied.
It did not handle LMTP DATA/BDAT command correctly, for which there can be multiple replies.
This fixes mixing local/remote recipients in LMTP, which used to crash:
Panic: file smtp-server-connection.c: line 610 (smtp_server_connection_next_reply): assertion failed: (cmd->state == SMTP_SERVER_COMMAND_STATE_READY_TO_REPLY && smtp_server_command_is_replied(cmd))
Stephan Bosch [Mon, 18 Dec 2017 14:20:07 +0000 (15:20 +0100)]
lib-smtp: command parser: Fix error recovery.
Input characters were not skipped upon error, meaning that error recovery would encounter these again.
This would make the parser parse the same data over and over again, yielding the same error.
This in turn caused the SMTP server application to hang in an infinite input loop, submitting error replies in the process, thereby filling up the process memory until exhaustion.
Problem seen in submission service, but LMTP is also affected.
Timo Sirainen [Mon, 18 Dec 2017 10:06:43 +0000 (12:06 +0200)]
lib-smtp: server: Fix panic when io_remove() is called too late
With submission-login the conn_disconnect() callback ends up in
login-common's client_disconnect(), which closes the file descriptor.
The io_remove() was done afterwards, which caused a crash:
submission-login: Panic: epoll_ctl(del, 18) failed: Bad file descriptor