1
0
mirror of https://blitiri.com.ar/repos/chasquid synced 2025-12-19 14:57:04 +00:00
Commit Graph

31 Commits

Author SHA1 Message Date
Alberto Bertogli
dd35085a32 Remove obsolete TODOs 2016-10-21 22:13:39 +01:00
Alberto Bertogli
eadd0ffc89 chasquid: Track and enforce the HELO/EHLO address
HELO and EHLO both take a mandatory parameter, which also should be used
in the Received header.

This patch tracks and enforces that parameter, and also updates the
Received header generation to use it.

https://tools.ietf.org/html/rfc5321#section-4.4
2016-10-21 22:13:39 +01:00
Alberto Bertogli
112e492c3a Normalize domains
We should ignore the domains' case, and treat them uniformly, specially when it
comes to local domains.

This patch extends the existing normalization (IDNA, keeping domains as
UTF8 internally) to include case conversion and NFC form for
consistency.
2016-10-10 00:51:05 +01:00
Alberto Bertogli
3eac221a7f chasquid: Make the "Received:" header RFC compliant
The Received header has some predefined structure and valid keywords,
this patch adjust how we create them to be compliant with that
structure.
2016-10-10 00:51:05 +01:00
Alberto Bertogli
bc2b3b40a5 chasquid: Skip SPF if the connection has authenticated
Currently, we do SPF checks for all connections.

However, authenticated users will be sending email from different
locations, applying SPF to them will result in false positives.

So this patch makes chasquid skip SPF checking if the connection is
authenticated.
2016-10-10 00:51:05 +01:00
Alberto Bertogli
40153e352f chasquid: Detect email loops
This patch implements some measures against email loops, such as keeping
a limit on the lenght of an address, and rejecting email that has too
many Received headers.

It's not perfect (a server could be actively removing Received headers),
but it should cover the normal accidents and misconfigurations.
2016-10-10 00:51:05 +01:00
Alberto Bertogli
2b801a84d1 chasquid: Add SPF checks
This patch makes chasquid perform SPF checks, and add the corresponding
Received-SPF header.
2016-10-10 00:51:05 +01:00
Alberto Bertogli
55b03c8cf0 queue: Use a local envelope-from when forwarding
If there's an alias to forward email to a non-local domain, using the original
From is problematic, as we may not be an authorized sender for it.

Some MTAs (like Exim) will do it anyway, others (like gmail) will construct a
special address based on the original address.

This patch implements the latter approach, which is safer and allows the
receiver to properly enforce SPF.

We construct a (hopefully) reasonable From based on the local user, and
embedding the original From (but transformed for IDNA, as the receiver may not
support SMTPUTF8).
2016-10-10 00:51:05 +01:00
Alberto Bertogli
6dda2fff4b chasquid: Introduce support for SMTPUTF8
This patch adds initial support for SMTPUTF8, which for now consists of just
advertising it.

We support most of it, but sending emails over SMTP requires further work, as
the SMTP courier does not support this yet (it's not in Go's standard
library). That will come in subsequent patches, along with IDNA handling.

https://tools.ietf.org/html/rfc6531.html
2016-10-10 00:51:04 +01:00
Alberto Bertogli
f767b83fe0 Implement basic IDNA support
This patch implements the first steps of support for IDNA (Internationalized
Domain Names for Applications).

Internally, we maintain the byte-agnostic representation, including
configuration.

We support receiving IDNA mail over SMTP, which we convert to unicode for
internal handling.

Local deliveries are still kept agnostic.

For sending over SMTP, we use IDNA for DNS resolution, but there are some
corner cases pending in the SMTP courier that are tied with SMTPUTF8 and will
be fixed in subsequent patches.
2016-10-10 00:51:04 +01:00
Alberto Bertogli
7fa40397c5 courier: SMTP falls back to A when MX does not exist
Make the SMTP courier fall back to the A record when MX does not exist, as per
standard behaviour.

This is not implemented nicely, because Go's API does not give a clear signal
if the answer was that there are no MX records or something else happens.
For now, we implement it with a heuristic that should work pretty reliably,
but it's definitely not very nice.
2016-10-10 00:51:04 +01:00
Alberto Bertogli
e138f0dc05 chasquid: De-couple TLS certificates from domains
Having the certificates inside the domain directory may cause some confusion,
as it's possible they're not for the same name (they should be for the MX we
serve as, not the domain itself).

So it's not a problem if we have domains with no certificates (we could be
their MX with another name), and we could have more than one certificate per
"domain" (if we act as MXs with different names).

So this patch moves the certificates out of the domains into a new certs/
directory, where we do a one-level deep lookup for the files.

While at it, change the names of the files to "fullchain.pem" and
"privkey.pem", which match the names generated by the letsencrypt client, to
make it easier to set up.  There's no general convention for these names
anyway.
2016-10-10 00:51:04 +01:00
Alberto Bertogli
0995eac474 chasquid: Fail at RCPT TO time if a user does not exist
It's more convenient and in line with standard practice to fail RCPT TO if the
user does not exist.

This involves making the server and client aware of aliases, but it doesn't
end up being very convoluted, and simplifies other code.
2016-10-10 00:51:04 +01:00
Alberto Bertogli
935494429d test: Add RACE=1 variable to run with the race detector
It's often useful to run the tests with the race detector (-race) enabled.
Unfortunately, building with it is too slow to enable unconditionally.

So for now this patch adds an option, in the form of an environment variable,
to enable it manually.
2016-10-10 00:51:04 +01:00
Alberto Bertogli
469cbd5d76 test: Add a test for DSN and null address deliveries
This patch adds a test for delivery status notifications and null address
deliveries, that check that chasquid can both receive and send DSNs.

To do this, we extend the mail_diff utility to support wildcards in the
comparisons, to skip over variable parts of the messages (like dates).
2016-10-10 00:51:04 +01:00
Alberto Bertogli
1d3675a133 queue: Send delivery status notifications on failures
When we permanently failed to deliver to one or more recipients, send delivery
status notifications back to the sender.

To do this, we need to extend a couple of internal structures, to keep track
of the original destinations (so we can include them in the message, for
reference), and the hostname we're identifying ourselves as (this is arguable
but we're going with it for now, may change later).
2016-10-10 00:51:04 +01:00
Alberto Bertogli
0bf5d9b242 Distinguish between permanent and transient errors
This patch makes the queue and couriers distinguish between permanent and
transient errors when delivering mail to individual recipients.

Pipe delivery errors are always permanent.

Procmail delivery errors are almost always permanent, except if the command
exited with code 75, which is an indication of transient.

SMTP delivery errors are almost always transient, except if the DNS resolution
for the domain failed.
2016-10-10 00:51:04 +01:00
Alberto Bertogli
3d06fb3a78 Turn chasquid-userdb into chasquid-util
This patch removes chasquid-userdb and adds a more generic and extensive
chasquid-util, that supports various operations on user databases as well as
aliases lookups.

The code is not very pretty but for now I took a more practical approach, the
tool is ancillary and can be tidied up later.
2016-10-10 00:51:04 +01:00
Alberto Bertogli
667358d72e courier: Tidy up the Procmail courier
This patch tidies up the Procmail courier:
 - Move the configuration options to the courier instance, instead of using
   global variables.
 - Implement more useful string replacement options.
 - Use exec.CommandContext for running the command with a timeout.

As a consequence of the first item, the queue now takes the couriers via its
constructor.
2016-10-10 00:51:04 +01:00
Alberto Bertogli
5f15b4e040 test: Skip exim test if the binary is not found
The exim test requires a bit more preparation than the rest, so skip it if the
binary is not found or not working properly.
2016-10-10 00:51:04 +01:00
Alberto Bertogli
c34c073c1c chasquid: Load and resolve aliases
This patch integrates the aliases resolution into the daemon and queue.

The queue now will resolve aliases at Put time.
2016-10-10 00:51:04 +01:00
Alberto Bertogli
aacf8ffea7 queue: Implement persistency
This patch makes the queue read and write items to disk.

It uses protobuf for serialization. We serialize to text format to make
manual troubleshooting easier, as the performance difference is not very
relevant for us.
2016-10-10 00:51:04 +01:00
Alberto Bertogli
9ed30a747b config: Add a "data_dir" option
This patch adds a "data_dir" option, that chasquid will use to store
persistent data. It defaults to "/var/lib/chasquid" (for now, at least).

Users will come in subsequent patches.
2016-10-10 00:51:04 +01:00
Alberto Bertogli
e9d62e0467 chasquid: Do a Chdir into the configuration directory
In some cases, it's be useful to have references to directories relative
to the configuration itself.

So this patch makes chasquid do a Chdir into it, so we can assume it in
the rest of the code and config.
2016-10-10 00:51:04 +01:00
Alberto Bertogli
394067bbd3 userdb: Use protocol buffers instead of our custom format
Protocol buffers are a more portable, practical and safe format for the user
database.
2016-10-10 00:51:03 +01:00
Alberto Bertogli
e2fdcb3705 Add checks to prevent unauthorized relaying and impersonation
This patch adds checks that verify:

 - The envelope from must match the authenticated user. This prevents
   impersonation at the envelope level (while still allowing bounces, of
   course).
 - If the destination is remote, then the user must have completed
   authentication. This prevents unauthorized relaying.

The patch ends up adjusting quite a few tests, as they were not written
considering these restrictions so they have to be changed accordingly.
2016-10-10 00:50:56 +01:00
Alberto Bertogli
941eb9315c Distinguish between SMTP and submission ports
We want to be able to distinguish between connections for SMTP and connections
for submission, so we can make different policy decisions.

To do that, we first make the configuration aware of the different kinds of
addresses. This is done in this patch in a backwards-incompatible way, but at
this point in time it is ok to do so.

Then, we extend systemd's socket passing library to support socket naming, so
we can tell the different sockets apart. This is done via the
LISTEN_FDNAMES/FileDescriptorName mechanism.

And finally we make the server and connection types aware of the socket mode.
2016-10-10 00:50:24 +01:00
Alberto Bertogli
69222284e0 test: Rename test directories to use an explicit order
For convenience, rename the directories so the order is explicit in the name.
Make the simple test run first, to save time if it's not working.
2016-09-12 04:06:56 +01:00
Alberto Bertogli
2c90281c11 test: Add top-level README and run script 2016-09-12 04:06:56 +01:00
Alberto Bertogli
905161c537 test: Add a test for Exim interactions
This patch adds a new test which makes chasquid send and receive email to/from
Exim.

To make it work we need to add two testing flags to the SMTP courier, which is
not ideal but doesn't muddle the code much.

The test is not very portable, and assumes an exim binary is available, but
does not have to be installed in the system. It includes a helper script to
fetch one from the Debian archives.
2016-09-12 04:06:56 +01:00
Alberto Bertogli
92a88bd06f test: Add a new local end-to-end test
This patch introduces a new directory, test/, which contains a simple local
end-to-end test which runs a chasquid binary and uses msmtp to send an email,
which is delivered locally.

As it's the first one, it adds a bunch of common infrastructure to simplify
writing these kinds of tests.

More end-to-end tests will follow, and it's expected that the common
infrastructure will also change significantly to accomodate their needs.
2016-09-12 04:06:56 +01:00