636 Commits

Author SHA1 Message Date
Alberto Bertogli
c8fbf2ecc9 smtpsrv: Don't consider client EOF an error
When the client closes the connection, which is very common, chasquid
logs it as an error ("exiting with error: EOF").

That can be confusing and mislead users, and also makes a lot of
traces be marked as errored, when nothing wrong occurred.

So this patch changes the log to not treat it as an error.
2020-03-21 16:58:56 +00:00
Alberto Bertogli
fcbd20cd74 docs: Add a section on dovecot auth troubleshooting
This patch adds a section on dovecot authentication troubleshooting,
with common suggestions that can help identify what is going on when
the chasquid-dovecot interaction isn't working as expected.
2020-03-21 16:54:39 +00:00
Alberto Bertogli
65afb02cd5 docs: Document the use of SRS when doing alias forwarding
When an alias has a remote destination, chasquid uses sender rewriting
(also known as SRS [1]) to forward the email without risking being in
violation of SPF policies.

See https://en.wikipedia.org/wiki/Sender_Rewriting_Scheme for more
details.

This, however, wasn't documented anywhere, as noted in
https://github.com/albertito/chasquid/issues/6.

This patch adds a paragraph to the alias documentation explaining this
behaviour.
2020-03-21 14:15:47 +00:00
Alberto Bertogli
8fab350b59 courier: DNS temporary errors should cause temporary delivery failures
In the SMTP courier, when the MX lookup fails with a DNS temporary
error, we should propagate that up and cause delivery to fail with a
temporary error too.

That way the delivery can be attempted later by the queue.

However, the code today doesn't make the distinction and will treat any
temporary DNS error as a permanent delivery failure, which is a bug.

The bug was found by ludusrusso and reported in
https://github.com/albertito/chasquid/issues/4

This patch fixes the bug by propagating the error properly.
2020-03-12 22:07:22 +00:00
Alberto Bertogli
6641d858ad courier: Extend TODO for DNS error handling on Go >= 1.13
In https://github.com/albertito/chasquid/issues/4, ludusrusso comments
that the DNS lookup error handling in the SMTP courier could be improved
by using DNSError.IsNotFound.

That is true, but unfortunately it was only added in Go 1.13, and we are
currently trying to support Go 1.11 since that's what in Debian stable.

So this patch updates the TODO to note this, so that when we can use a
newer Go version, we improve this code.
2020-03-12 22:07:11 +00:00
Alberto Bertogli
150976b905 test: Use a pretty table for the coverage html
This patch improves the readability and usability of the generated
coverage HTML by making the list of files be a table.
2020-03-04 00:59:37 +00:00
Alberto Bertogli
a1ca50ab57 hooks: Add mising quote in the example post-data hook
The example post-data hook was missing a quote around a sub-shell
execution.

This is harmless because the content itself is admin-provided and not
related to user input, but this commit fixes the quote for defense in
depth and consistency.
2020-02-02 02:07:38 +00:00
Alberto Bertogli
0df2e325ed docs: v1.2 release notes 2019-12-06 15:33:07 +00:00
Alberto Bertogli
8f2eba5795 docs: Add release notes, replacing the upgrading notes
This patch replaces the upgrading notes, which focused only on
backwards-incompatible changes, with more detailed release notes.
2019-12-06 15:19:50 +00:00
Alberto Bertogli
4edcd79a25 smtpsrv: Keep reading DATA input even if it's too large
When the DATA input is too large, we should keep on reading through it
until we reach the end marker, otherwise there is a security problem:
the remaining data will be interpreted as SMTP commands, so for example
a forwarded message that is too long might end up executing SMTP
commands under an authenticated user.

This patch implements this behaviour, while being careful not to consume
extra memory to avoid opening up the possibility of a DoS.

Note the equivalent logic for single long lines is already implemented.
2019-12-04 01:46:54 +00:00
Alberto Bertogli
28cb9169cc test: Add SPF integration test
This patch adds a new integration test to cover SPF checks. The main
goal is not to cover the SPF parsing, since that's handled by the
library already, but the higher level aspects: that the mails are indeed
rejected, that the DSN looks reasonable, etc.
2019-12-01 22:13:31 +00:00
Alberto Bertogli
6000d07ad0 test: Test multiline headers in hook output
Hook output is checked to see if it looks like a header, which includes
the possibility of multi-line headers.

This patch extends the tests to include a multi-line header, to prevent
accidental regressions.
2019-12-01 20:38:50 +00:00
Alberto Bertogli
45a294403d test: Test permanent hook failure
This patch adds a test to make sure we handle correctly the case where a
hook exits with a permanent failure.
2019-12-01 20:31:59 +00:00
Alberto Bertogli
a12875162f smtpsrv: Test too many recipients
This patch adds a test to make sure we don't allow too many recipients.
2019-12-01 19:37:47 +00:00
Alberto Bertogli
99c4ad5ef7 smtpsrv: Disable reloads during tests
Reloading during tests will cause the testing aliases to be removed,
which makes test runs that extend beyond 30s to be flaky.

This patch fixes the bug by disabling reloads during these tests.
2019-12-01 19:09:58 +00:00
Alberto Bertogli
e8a6bf6188 smtpsrv: Make tests log maillog to stdout 2019-12-01 19:09:57 +00:00
Alberto Bertogli
a6a964ac3e test: Move testing couriers to testlib
The testing couriers are currently only used in the queue tests, but we
also want to use them in smtpsrv tests so we can make them more robusts
by checking the emails got delivered.

This patch moves the testing couriers to testlib, and makes both queue
and smtpsrv use them.
2019-12-01 19:09:12 +00:00
Alberto Bertogli
99df5e7b57 smtpsrv: Limit incoming line length and improve large message handling
Currently, there is no limit to incoming line length, so an evil client
could cause a memory exhaustion DoS by issuing very long lines.

This patch fixes the bug by limiting the size of the lines.

To do that, we replace the textproto.Conn with a pair of buffered reader
and writer, which simplify the code and allow for better and cleaner
control.

Thanks to Max Mazurov (fox.cpp@disroot.org) for finding and reporting
this issue.
2019-12-01 19:07:58 +00:00
Alberto Bertogli
d7006d0e16 smtp: Limit incoming line length
On the smtp client package, there is no limit to the length of the
server's replies, so an evil server could cause a memory exhaustion DoS
by issuing very long lines.

This patch fixes the bug by limiting the total size of received data.
Ideally this would be done per-line instead, but gets much more complex,
so this is a compromise.

The limit chosen is 2 MiB, which should be plenty for any the total size
of server-side replies, considering we only send a single message per
connection anyway.

This is similar to 06d808c (smtpsrv: Limit incoming line length), which
was found and reported by Max Mazurov (fox.cpp@disroot.org).
2019-12-01 17:25:25 +00:00
Alberto Bertogli
bf01fab893 travis: Increase minimum supported version to 1.11
We want Travis CI to check against the Go version shipped in the latest
Debian stable, to make sure chasquid can be built and run there.

There was a new Debian release which has Go 1.11, so raise the CI config
version accordingly.
2019-12-01 17:25:25 +00:00
Alberto Bertogli
34339c4572 smtpsrv: Add fuzz testing
This patch adds a fuzz test for the smtpsrv package.

It brings up a server for test, and then fuzz the data sent over the
network.
2019-11-30 11:38:46 +00:00
Alberto Bertogli
933b979220 smtpsrv: Don't hard-code ports in tests
The smtpsrv tests hard-code ports, but this patch fixes that by making it
use the new testlib.GetFreePort function.
2019-11-30 11:38:46 +00:00
Alberto Bertogli
d0f65881c9 smtpsrv: Allow manual override of submission+TLS port in tests
The smtpsrv server tests allow manual override of testing ports via
flags, but the submission+TLS port was missing (accidental oversight).
2019-11-30 11:38:46 +00:00
Alberto Bertogli
ac2c5ab4db test: Add testlib.GetFreePort function
Some tests require picking ports, and today resort to hard-coding,
which is brittle.

This patch adds a testlib.GetFreePort function to help pick free ports.

It is not totally race-free, but is much better than hard-coding.
2019-11-30 11:38:46 +00:00
Alberto Bertogli
87e5acde59 docs: Add missing reference to upgrading.md in the index 2019-10-31 21:40:15 +00:00
Alberto Bertogli
0c92fb4937 docs: Add section about monitoring with Prometheus
This patch adds a section to the monitoring docs with an example of how
to use the prometheus-expvar-exporter to monitor chasquid with
Prometheus.
2019-10-31 21:38:34 +00:00
Alberto Bertogli
8b80e9fc2e docs: Add missing monitoring expvar, correct minor wording 2019-10-31 21:36:58 +00:00
Alberto Bertogli
a75eabbc22 test: Generate a prettier coverage report
To make the coverage report a bit more accessible and easier to
navigate, this patch makes the coverage tests generate a new HTML
coverage report (in addition to the classic variant).
2019-10-26 01:56:33 +01:00
Alberto Bertogli
809578cb57 README: Update links and shields
This patch updates the README file, adjusting some of the existing
references, as well as adding new ones (mainly pointing to new
documentation).
2019-10-25 16:00:15 +01:00
Alberto Bertogli
e8511e3f55 docs: Update install/build documentation
This patch updates the installation guide to try to make the
installation section more readable.

It also assumes a modern Go environment is installed, which
simplifies the process of building from source.
2019-10-25 16:00:15 +01:00
Alberto Bertogli
a47faf89a4 smtpsrv: Failures to enqueue are transient, not permanent
If we fail to put the message in the queue (e.g. because we're out of
storage space, or the aliases-resolve hook errored out), it should be
considered a transient failure.

Currently we return a permanent error, which is misleading, as we want
clients to retry in these situations.

So this patch changes the error returned accordingly.
2019-10-24 21:37:09 +01:00
Alberto Bertogli
0718749314 Update auto-generated code
This patch updates the auto-generated code to match the latest tooling
versions.

In particular, the protobufs are regenerated, and the new version no
longer supports unkeyed literals, so some minor changes are needed.

Other than that, the cipher list is extended with the latest ciphers.
2019-10-24 21:37:09 +01:00
Alberto Bertogli
f399fe3e84 aliases: Implement aliases hooks
This patch implements two new hooks: alias-resolve and alias-exists.

They are called during the aliases resolution process, to allow for more
complex integration with other systems, such as storing the aliases in a
database.

See the included documentation for more details.
2019-10-24 21:37:09 +01:00
Alberto Bertogli
dea6f73164 aliases: Treat empty pipe aliases as bad lines and skip them
A pipe alias must have a command, if it doesn't, we should treat the
line as bad and skip it like we do for others.
2019-10-22 22:14:26 +01:00
Alberto Bertogli
5f72f723db smtpsrv: Clean up post-data hook tracing output
This patch does some cleanups on the tracing output for the post-data
hook, to quote the output better and more consistently.
2019-10-22 21:45:54 +01:00
Alberto Bertogli
5782a7705e hooks: Add rspamd integration to the example hook
Rspamd (https://rspamd.com/) is a popular open-source spam filtering
system.

This patch adds integration with it in the example hook, which uses the
rspamc client to get a veredict, similar to what it does for
Spamassassin.
2019-10-21 13:51:58 +01:00
Alberto Bertogli
27227986ab smtp-check: Improve error reporting
smtp-check exits on the first error, which is not ideal when
troubleshooting, as seeing only one error can mask others, or make it
more difficult to find the underlying cause.

This patch improves how smtp-check reports errors by tweaking the
presentation a bit, as well as perform almost all checks regardless of
whether they pass or not.
2019-10-19 14:26:47 +01:00
Alberto Bertogli
0bf8f72c73 docs: Add documentation about tests
This patch replaces test/README, which was becoming a bit outdated, with
a more general description of the different tests at a high level, and
includes it in the documentation index.
2019-10-19 13:06:30 +01:00
Alberto Bertogli
605e39d0e3 test: Extend chasquid-util aliases-add tests 2019-10-19 13:06:30 +01:00
Thor77
8d910fc84d Add aliases-add subcommand to chasquid-util 2019-10-19 13:06:30 +01:00
Alberto Bertogli
9dea372d96 gitlab-ci.yml: Run integration tests against submitted and latest deps
It is useful to run the integration tests both against the submitted
dependencies, based on Go module versions from the repository, as well
as the latest ones, to catch integration problems early.

This patch extends the .gitlab-ci.yml configuration to do that, by
optionally passing a flag to "go get" to update the modules.
2019-10-19 13:06:30 +01:00
Alberto Bertogli
3aa7bb4555 test: Adjust Dockerfile to support modules
When modules are configured, go will now attempt to fetch them on build,
using the proxy.

That causes the integration tests run via Docker to fail, because go
build attempts to contact the proxy within the test environment, which
has the external DNS resolvers disabled.

This patch fixes the problem by adjusting the pre-run fetch to use the
new modules system. We fetch the dependencies to the cache so that when
they're needed within the environment, they are present and there's no
need to use the proxy.
2019-10-19 13:06:26 +01:00
Thor77
80b4f7f832 Add support for go modules 2019-10-19 00:45:18 +01:00
Alberto Bertogli
5fa756fddc docs: Clarify how users are identified to dovecot
In authentication requests sent to dovecot, chasquid uses the full
addresses, "user@domain". However this wasn't mentioned in the
documentation, and could cause some confusion.

So this patch adds an explicit clarification about this in the dovecot
integration documentation.
2019-10-19 00:45:18 +01:00
Alberto Bertogli
bb97991a24 docs: Add aliases documentation
The processing of aliases wasn't properly documented in an user-visible
way, so this patch adds a new section for it.
2019-10-19 00:45:18 +01:00
Alberto Bertogli
41d960590d smtpsrv: Use spf.CheckHostWithSender
The spf library has gained support for macros, but to process them
properly, a new function needs to be called with the full sender
address, spf.CheckHostWithSender.

This patch updates chasquid's calls to the new API.
2019-10-14 19:37:14 +01:00
Alberto Bertogli
3584441549 test: Use testlib.RemoveIfOk where appropriate
Some tests did not make use of testlib.RemoveIfOk, which resulted in
some duplication; this patch fixes that.

While at it, userdb tests have its own simpler variant, so add some
safety checks to it.
2019-09-10 01:09:44 +01:00
Alberto Bertogli
34ade50374 test: Work around msmtp having setgid permissions
In some distributions, including newer Debian versions, msmtp is
installed as setgid.

That prevents $HOSTALIASES from being honoured, which breaks the tests.

This patch works around the problem by creating a copy of the binary,
which will not have the setgid bit set.
2019-08-31 01:27:19 +01:00
Alberto Bertogli
f63e5bf0b2 sts: Reject policies with max_age > 1y, as per RFC
The MTA-STS standard explicitly says the maximum max_age is 1 year.

This patch adds a check to the STS library to enforce this. Policies
with max_age > 1y will be treated as invalid.

See this email thread for some discussion on the topic:
https://mailarchive.ietf.org/arch/msg/uta/bnUjy9jxM_Va-lDXVtbB32zIkYI
2019-08-31 01:14:56 +01:00
Alberto Bertogli
0f487e5fb5 test: Remove dependency on Python 2
Python 2 is approaching end of life, and we only need it to run
the mail_diff test utility.

This patch updates mail_diff to run on Python 3, which only needed minor
changes.
2019-08-30 09:46:46 +01:00