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

102 Commits

Author SHA1 Message Date
Alberto Bertogli
cb6500b993 sts: Don't use expvar.Int.Value in tests, for Go 1.7 compatibility
expvar.Int.Value appeared in Go 1.8, but we want to keep compatibility
with Go 1.7 at least until the next release.

So this patch replaces the use of expvar.Int.Value in tests, to make
them compatible with Go 1.7 again.
2017-03-01 10:14:39 +00:00
Alberto Bertogli
9539cfd34d courier: Consider not finding any MX/A records a permanent error
Currently, if we can't find a mail server for a domain, we consider that
a transient failure (semi-accidentally, as we iterate over the (empty)
list of MXs and fall through the list).

It should be treated as a permanent error, in line with other DNS
issues (which is not ideal but seems to be generally accepted
behaviour).
2017-03-01 00:22:49 +00:00
Alberto Bertogli
0eeb964534 sts: Limit the size of the HTTPS reads
To avoid accidents/DoS when we are fetching a very very large policy,
this patch limits the size of the reads to 10k, which should be more
than enough for any reasonable policy as per the current draft.
2017-03-01 00:10:10 +00:00
Alberto Bertogli
e66288e4b4 sts: Make tests more end-to-end, to cover HTTP fetching
The current tests stop short of fetching over HTTP, but that code is
unfortunately not trivial.

This patch changes the testing strategy to use a testing HTTP server,
which we point our URLs to. That way we can cover much more code with the
same tests.
2017-03-01 00:10:10 +00:00
Alberto Bertogli
216cf47ffa courier: Add STS policy checking to the SMTP courier
This patch extends the SMTP courier to (optionally) do STS policy
checking when delivering mail.

As STS support is currently experimental, we gate this behind a flag and
is disabled by default.
2017-02-28 22:27:15 +00:00
Alberto Bertogli
d66b06de51 sts: Add an on-disk cache implementation
This patch adds an on-disk cache for STS policies.

Policies are cached by domain, and stored on files in a single
directory.  The files will have as mtime the time when the policy
expires, this makes the store simpler, as it can avoid keeping
additional metadata.

There is no in-memory caching. This may be added in the future, but for
now disk is good enough for our purposes.
2017-02-28 22:27:15 +00:00
Alberto Bertogli
79c0a17328 safeio: Extend WriteFile to take operations before the final rename
This patch extends WriteFile to allow arbitrary operations to be applied
to the file before it is atomically renamed.

This will be used in upcoming patches to change the mtime of the file
before it is atomically renamed.
2017-02-28 22:27:15 +00:00
Alberto Bertogli
fe00750e39 sts: Treat missing/empty "mx" list as invalid
The "mx" field is required, a policy without it is invalid, so add a
check for it.

See
https://mailarchive.ietf.org/arch/msg/uta/Omqo1Bw6rJbrTMl2Zo69IJr35Qo
for more background, in particular the following paragraph:

> The "mx" field is required, so if it is missing, the policy is invalid
> and should not be honored. (It doesn't make sense to honor the policy
> anyway, I would say, since a policy without allowed MXs is essentially a
> way of saying, "There should be TLS and the server identity should match
> the MX, whatever the MX is." I guess this prevents SSL stripping, but
> doesn't prevent DNS injection, so it's of relatively little value.)
2017-02-28 22:27:15 +00:00
Alberto Bertogli
933ab54cd8 sts: Experimental MTA-STS (Strict Transport Security) implementation
This EXPERIMENTAL patch has a basic implementation of MTA-STS (Strict
Transport Security), based on the current draft at
https://tools.ietf.org/html/draft-ietf-uta-mta-sts-02.

It integrates the policy fetching and checking into the smtp-check tool
for convenience, but not yet in chasquid itself.

This is a proof of concept. Many features and tests are missing; in
particular, there is no caching at all yet.
2017-02-28 22:27:15 +00:00
Alberto Bertogli
b8551729db smtp: Try all entries in MX, not just the first one
Currently, we pick the first host in the MX list, and attempt delivery
there. If it fails, we just report the failure to the queue, which will
wait for some time and then try again.

This is not ideal: we should fall back to the other MXs in the list, as
the first host could be having issues for a long time, and not
attempting with the rest just delays delivery.

This patch implements the fallback, so we try all MXs before deciding to
report a failed delivery (unless, of course, an MX returned a permanent
failure).
2017-02-28 22:27:15 +00:00
Alberto Bertogli
6479138c57 log: Add a symbol for Fatal log entries
Currently there is no symbol for Fatal-level log entries, so they appear
with "-2", which is distracting.

This patch makes the Fatal log entries have their own symbol, ☠.
2016-11-24 10:18:04 +00:00
Alberto Bertogli
75cc038e68 smtpsrv: Fail to listen if there are no certificates configured
The server is written assuming there's at least one valid SSL/TLS
certificate. For example, it unconditionally advertises STARTTLS, and
only supports AUTH over TLS.

This patch makes the server fail to listen if there are no certificates
configured, so the users don't accidentally run an unsupported
configuration.
2016-11-24 10:09:11 +00:00
Alberto Bertogli
de09923933 smtpsrv: Disable SPF lookups in tests
When testing, we don't want the server to do SPF lookups, as those cause
real DNS queries which can be problematic and add a dependency on the
environment.

This patch adds an internal boolean to disable the SPF lookups, which is
only set from the tests.
2016-11-22 22:05:07 +00:00
Alberto Bertogli
f7cdbae8e3 Fix minor typos and formatting directives
This small patch fixes a typo in a comment, and a missing formatting
directive; both were caught by static analysis tools (misspell and go
vet).
2016-11-20 18:32:26 +00:00
Alberto Bertogli
249831064f courier: Skip test if test/util/exitcode is not found
When building the Debian package, the tests are run in such a way that
test/util/exitcode is not found, which causes them to fail.

This patch is a workaround which skips the test if test/util/exitcode is
not found; for now we should consider it temporary, until either the
Debian packaging is fixed, or we decide that its environment is
reasonably enough to make it permanent.
:
2016-11-20 18:30:30 +00:00
Alberto Bertogli
fea808f8e3 queue: Get the DSN domain from the message
Picking the domain used in the DSN message "From" header is more
complicated than it needs to be, causing confusing code paths and having
different uses for the hostname, which should be purely aesthetic.

This patch makes the queue pick the DSN "From" domain from the message
itself, by looking for a local domain in either the sender or the
original recipients. We should find at least one, otherwise it'd be
relaying.

This allows the code to be simplified, and we can narrow the scope of
the hostname option even further.
2016-11-03 00:51:59 +00:00
Alberto Bertogli
cf2b8ade65 etc: Add a skeleton configuration structure
This patch adds an "etc" directory, with a basic configuration structure
that can be used for an initial installation.
2016-11-01 23:56:04 +00:00
Alberto Bertogli
54cce0c2bf test: Reduce the loop detection threshold from 50 down to 5
The loop test can be quite slow, specially on computers without
cryptography-friendly instructions.

This patch introduces a new flag for testing, so that we can bring the
threshold down to 5. The test is just as useful but now runs in a few
seconds, as opposed to a few minutes.
2016-11-01 23:56:04 +00:00
Alberto Bertogli
8cbc4f9ca6 queue: Use a PRNG to generate IDs
The queue IDs are internal to chasquid, and we don't need them to be
cryptographically secure, so this patch changes the ID generation to use
the PRNG.

This also helps avoid entropy issues.
2016-11-01 23:56:04 +00:00
Alberto Bertogli
1bc111f783 Improve the readability of some log messages
This patch contains a few changes to logging messages, to improve log
readability.

While at it, an obsolete TODO in the SMTP courier is removed.
2016-11-01 23:56:04 +00:00
Alberto Bertogli
60a7932bd3 log: Replace glog with a new logging module
glog works fine and has great features, but it does not play along well
with systemd or standard log rotators (as it does the rotation itself).

So this patch replaces glog with a new logging module "log", which by
default logs to stderr, in a systemd-friendly manner.

Logging to files or syslog is still supported.
2016-11-01 23:56:04 +00:00
Alberto Bertogli
6640c09b9e smtpsrv: Always pass the environment variables to the hook
This patch makes the hooks always have a complete set of environment
varuables, set to 0/1 or whatever is appropriate, to make it easier to
write the checks for them.
2016-10-22 18:55:09 +01:00
Alberto Bertogli
14c48153aa smtpsrv: If the hook exits with code 20, it's a permanent failure
It is can be convenient for hooks to indicate that an error is
permanent; for example if the anti-virus found something.

This patch makes it so that if the hook exits with code 20, then it's
considered permanent. Otherwise it is considered transient, to help
prevent accidental errors cause final delivery issues.
2016-10-22 18:55:02 +01:00
Alberto Bertogli
38b4e76090 spf: Support the "ptr" mechanism
The "ptr" mechanism should not be used, but unfortunately many domains
still do.

This patch extends our SPF implementation to support checking it.

https://tools.ietf.org/html/rfc7208#section-5.5
2016-10-22 00:07:07 +01:00
Alberto Bertogli
c00648b4ae queue: Calculate next delay based on creation time
Calculating the next delay based on the previous delay causes daemon
restarts to start from scratch, as we don't persist it.

This can cause a few server restarts to generate many unnecessary sends.

This patch changes the next delay calculation to use the creation time
instead, and also adds a <=1m random perturbation to avoid all queued
emails to be retried at the exact same time after a restart.
2016-10-21 22:20:49 +01:00
Alberto Bertogli
8e9e4eddc5 queue: Rewrite the aliases test to remove races
TestAliases is unfortunately racy, and cause occasional failures.

This patch rewrites it to be more end-to-end, similar to TestBasic,
which should remove the races while keeping the main objectives of the
test.
2016-10-21 22:20:49 +01:00
Alberto Bertogli
d660f88f67 queue: Send DSN for messages that time out in the queue
The queue currently only considers failed recipients when deciding
whether to send a DSN or not. This is a bug, as recipients that time out
are not taken into account.

This patch fixes that issue by including both failed and pending
recipients in the DSN.

It also adds more comprehensive tests for this case, both in the queue
and in the dsn generation code.
2016-10-21 22:20:49 +01:00
Alberto Bertogli
febe96697a maillog: Introduce a special-purpose mail logging package
The default INFO logs are more oriented towards debugging and can be
a bit too verbose when looking for high-level information.

This patch introduces a new "maillog" package, used to log messages of
particular relevance to mail transmission at a higher level.
2016-10-21 22:20:47 +01:00
Alberto Bertogli
cda11e03a5 safeio: Preserve file ownership
This patch makes safeio preserve file ownership. This is specially
useful when using command-line utilities as root, but the files they
change are owned by a different user.
2016-10-21 22:18:53 +01:00
Alberto Bertogli
ac7f32c2ce smtpsrv: Implement a post-DATA hook
This patch implements a post-DATA hook, which is run after receiving the
data but before sending a reply.

It can be used to implement content filtering when receiving email, for
example for passing the email through an anti-spam or an anti-virus.
2016-10-21 22:18:53 +01:00
Alberto Bertogli
5faffbbfe3 courier: Simplify procmail's execution logic
The way the procmail courier runs the command is unnecessary convoluted,
this patch simplifies it by using the corresponding standard tools.
2016-10-21 22:18:53 +01:00
Alberto Bertogli
88868d7d8e smtpsrv: Sanitize unknown commands
Unknown commands can fill the logs, traces and expvars with a lot of
noise; this patch sanitizes them a bit down to 6 bytes, as a compromise
to maintain some information for troubleshooting.
2016-10-21 22:18:53 +01:00
Alberto Bertogli
f5e466eac5 smtpsrv: Include the mode in the Received header
Including the mode (SMTP/submission) in the Received header can be
useful for troubleshooting transport issues.
2016-10-21 22:18:53 +01:00
Alberto Bertogli
c2d0d5f705 smtpsrv: Only allow authenticated email on submission
The submission port is expected to be used only by authenticated
clients, so this patch makes chasquid enforce this, which also helps
to reduce spam.

https://www.rfc-editor.org/rfc/rfc6409.txt
2016-10-21 22:18:53 +01:00
Alberto Bertogli
fe146f00e5 queue: Always use the main domain for sending DSNs
Today, we pick the domain used to send the DSN from based on what we
presented to the client at EHLO time, which itself may be based on the
TLS negotiation (which is not necessarily trusted).

This is complex, not necessarily correct, and involves passing the
domain around through the queue and persisting it in the items.

So this patch simplifies that handling by always using the main domain
as specified by the configuration.
2016-10-21 22:18:53 +01:00
Alberto Bertogli
b8c0ac98f4 chasquid: Split Server and Conn
This patch moves chasquid's Server and Conn structures to their own
smtpsrv package, to make chasquid.go a bit more readable. It also helps
clarify the relation between Server and Conn.

There are no functional changes.

Note that git can still track the history across this commit (e.g. git
gui blame shows the right data).
2016-10-21 22:18:48 +01:00
Alberto Bertogli
c013c98283 domaininfo: New package to track domain (security) information
This patch introduces a new "domaininfo" package, which implements a
database with information about domains.  In particular, it tracks
incoming and outgoing security levels.

That information is used in incoming and outgoing SMTP to prevent
downgrades.
2016-10-21 22:15:09 +01:00
Alberto Bertogli
1d7a207e00 Minor code aesthetic improvements, based on vet+fmt+lint
This patch is the result of running go vet, go fmt -s and the linter,
and fixing some of the things they noted/suggested.

There shouldn't be any significant logic changes, it's mostly
readability improvements.
2016-10-21 22:13:39 +01:00
Alberto Bertogli
a5e6e197a6 trace: Quote errors before logging them
Errors can contain newlines, in particular this is common in messages
returned by remote SMTP servers.

This patch quotes them before logging, they don't interfere with the
log. Note the tracer itself can handle this just fine.
2016-10-21 22:13:39 +01:00
Alberto Bertogli
09d3c73f6c queue: Simplify sending loop
This patch simplifies the sending loop code:

 - Move the recipient sending function from a closure to a method.
 - Simplify the status update logic: we now update and write
   unconditionally (as we should have been doing).
 - Create a function for counting recipients in a given status.

It also adds a test for the removal of completed items from the queue,
which was not covered before and came up during development.
2016-10-21 22:13:39 +01:00
Alberto Bertogli
dd35085a32 Remove obsolete TODOs 2016-10-21 22:13:39 +01:00
Alberto Bertogli
aa0486b54e protoio: Add a generic protobuf store
This patch adds a generic protobuf store, where one can put and retreive
protobufs, indexed by a string.

This will be used in subsequent patches.
2016-10-10 01:32:55 +01:00
Alberto Bertogli
cf36003e3a trace: Add an EventLog
This patch adds an EventLog wrapper to the trace module, which will be
used in the future to track long-lived objects.
2016-10-10 00:51:05 +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
ad25706d72 Normalize local usernames using PRECIS
This patch implements local username normalization using PRECIS
(https://tools.ietf.org/html/rfc7564,
https://tools.ietf.org/html/rfc7613)

It makes chasquid accept local email and authentication regardless of
the case. It covers both userdb and aliases.

Note that non-local usernames remain untouched.
2016-10-10 00:51:05 +01:00
Alberto Bertogli
220b5d20ff trace: Set max events to 30 by default
The default for max events is 10, which is a bit short for a normal SMTP
exchange. Expand it to 30 which should be large enough to keep most of
the traces.
2016-10-10 00:51:05 +01:00
Alberto Bertogli
2b46f300ca trace: Include debug messages in the traces
We don't want to write debug messages to the log, but having them in
traces is always useful.

The traces are volatile and self-cleaning so the additional volume
should not cause any problems, and helps troubleshooting.

While at it, fix the depth constant when logging.
2016-10-10 00:51:05 +01:00
Alberto Bertogli
3e55b0d742 courier/smtp: Reorder EHLO domain logic
The logic that picks the domain we use for EHLO does not need to live
within the TLS retry cycle, and makes it harder to understand.

This patch moves it out of the way, to improve readability.
2016-10-10 00:51:05 +01:00
Alberto Bertogli
c4e8b22fd0 Introduce expvar counters
This patch introduces expvar counters to chasquid and the queue
packages.

For now there's only a handful of counters, but they will be expanded in
future patches.
2016-10-10 00:51:05 +01:00
Alberto Bertogli
641406cede queue: Fix race in tests
The test courier has a racy map access, and this started to manifest
after some recent changes. This patch fixes the race by implementing the
corresponding locks.
2016-10-10 00:51:05 +01:00