636 Commits

Author SHA1 Message Date
Alberto Bertogli
f7a4fa895c test: Work around wget's logging to files
There's a bug in wget where it logs to files if -q is used:
https://savannah.gnu.org/bugs/?51181

It is harmless to the test, but it clutters the directory and the test
output, so this patch works around the issue by forcing it to log to
/dev/null.
2017-12-08 13:57:25 +00:00
Alberto Bertogli
94c4492862 test/t-01-simple_local: Don't fail if test certificates are missing
The test starts by removing the previous test certificates, which may
or may not exist.

If they don't, currently "rm" fails, causing the whole test to fail.
I am surprised I did not notice this before :(

This patch fixes the bug by using "rm -f" to remove the test certs.
2017-12-08 13:56:04 +00:00
Alberto Bertogli
b3592b7bf9 chasquid: Add package-level documentation 2017-11-19 13:49:54 +00:00
Alberto Bertogli
033a5d657b Use the external log, spf and systemd packages
The log, spf and systemd packages have been externalized; use them
instead of the internal version to avoid having two versions of the same
thing.
2017-09-17 22:17:14 +01:00
Alberto Bertogli
72477c0cfd smtpsrv: Get TLS information for direct connections
For direct TLS connections, such as submission-over-TLS, we currently
don't get the TLS information so it appears in the headers as "plain
text", which is misleading.

This patch fixes the problem by getting the connection information
early. Note it explicitly triggers the handshake, which would otherwise
happen transparently on the first read/write, so we can use the hostname
(if any) in our hello message.
2017-09-10 11:20:57 +01:00
Alberto Bertogli
0972964722 mda-lmtp: Handle "<>" addresses
Either the recipient or from addresses can be "<>" to indicate the null
address. mda-lmtp does not handle that well, as it sends "<<>>" which is
invalid.

This patch fixes that by special-casing them, which is unfortunate but
reasonably common.
2017-08-08 09:12:53 +01:00
Alberto Bertogli
6867859d5c courier: Make the SMTP test not use the network
One of the SMTP tests was doing an external DNS lookup for a
non-existing host, which is reasonably harmless but makes the test less
hermetic.

This patch changes the non-existing host for an invalid address, which
has the same effect but avoids the network lookup.

This is a hack; ideally we would be able to override the resolver, but
Go does not implement that yet, and changing the code is not worth the
additional complexity.
2017-07-16 13:24:40 +01:00
Alberto Bertogli
5426be5aec Add notes for upgrading
This patch adds an UPGRADING.md file containing notes for upgrading
between different versions.
2017-07-15 15:24:52 +01:00
Alberto Bertogli
9864f40f3b test: Tidy up creation and removal of test directories
We have many places in our tests where we create temporary directories,
which we later remove (most of the time). We have at least 3 helpers to
do this, and various places where it's done ad-hoc (and the cleanup is
not always present).

To try to reduce the clutter, and make the tests more uniform and
readable, this patch introduces two helpers in a new "testutil" package:
one for creating and one for removing temporary directories.

These new functions are safer, better tested, and make the tests more
consistent.  All the tests are updated to use them.
2017-07-14 02:02:43 +01:00
Alberto Bertogli
9388b396ee aliases: Normalize right-hand side addresses
The right-hand side addresses of an alias should be normalized, to
maintain the internal invariant that we always deal with normalized
addresses.

Otherwise, strange situations may arise, such as the same domain having
two different domaininfo structures depending on case.
2017-07-14 01:06:09 +01:00
Alberto Bertogli
a016d78515 courier: Fix SMTP outgoing security level check
The outgoing security level checks are not being performed, because of a
bug: the courier thinks the "to"'s domain is always empty.

This patch fixes the bug by simplifying the logic, as there's no need
for the conditional (there is always a domain in the "to" address if it
got to the SMTP courier).
2017-07-14 01:06:09 +01:00
Alberto Bertogli
a85ba1252b test: Remove nc.py
The nc.py script is only used in a single test, and for waiting for a
TCP port to be opened for listening.

This patch replaces it entirely, by using chamuyero for the test, and
bash for waiting on a TCP port.
2017-07-13 22:05:45 +01:00
Alberto Bertogli
82a1e4597f mda-lmtp: Add a very basic MDA that uses LMTP to do the mail delivery.
mda-lmtp is a very basic MDA that uses LMTP to do the mail delivery.

It takes command line arguments similar to maildrop or procmail, reads an
email via standard input, and sends it over the given LMTP server.
Supports connecting to LMTP servers over UNIX sockets and TCP.

Since chasquid does not support direct LMTP local delivery, this can be
used as a workaround instead.

Example of use:
$ mda-lmtp --addr localhost:1234 -f juan@casa -d jose < email
2017-07-13 22:05:45 +01:00
Alberto Bertogli
10427d7f49 test: Add "chamuyero", a tool to test line-oriented I/O
This patch adds "chamuyero", a a tool to test and validate line-oriented
commands and servers.

It can launch and communicate with other processes, and follow a script of
line-oriented request-response, validating the dialog as it goes along.

This can be used to test line-oriented network protocols (such as SMTP) or
interactive command-line tools.

It will be used in follow up patches to test new commands and
functionality.
2017-07-13 22:05:45 +01:00
Alberto Bertogli
2caaec3d8b userdb: Use a constant-time byte comparison in PasswordMatches
PasswordMatches calculates the proposed derived key, and then compares
it with the actual derived key. That comparison is done using
bytes.Equal, which is not in constant time.

In theory, users with knowledge of the salt could use timing to extract
information about the actual derived key.

In practice, the salt is not being exposed to users, and the caller of
PasswordMatches will add a delay to password checks, so it should not be
easy to exploit via chasquid.

But just to be safe and more future-proof, this patch changes the
comparison to be in constant time.
2017-04-26 10:26:54 +01:00
Alberto Bertogli
17eff21279 Only fail if there is no address to listen on at all, regardless of mode
Currently, chasquid exits if any mode (SMTP/submission/submission+tls)
has no addresses to listen on. This means that chasquid must be given
addresses for all three.

While that's generally the expected configuration, there are cases where
users may not want to have all three.

So this patch replaces that fatal error with a warning, and only makes
chasquid exit if there are no addresses to listen on at all.
2017-04-12 10:32:41 +01:00
Alberto Bertogli
7f5bedf4aa Remove the MTA-STS (Strict Transport Security) implementation
This commit removes the experimental MTA-STS (Strict Transport Security)
implementation for now, as it's not up to date with the latest draft.

Development will continue on the "sts" branch, but this way it won't
block releases until it is ready.

Commits reverted:
 - cb6500b993
 - 0eeb964534
 - e66288e4b4
 - 216cf47ffa
 - d66b06de51
 - fe00750e39
 - 933ab54cd8
2017-04-11 00:58:59 +01:00
Alberto Bertogli
213bc63a95 Support submission (directly) over TLS (submissions/smtps/port 465)
This patch adds support for TLS-wrapped submission connections.

Instead of clients establishing a connection over plain text and then
using STARTTLS to switch over a TLS connection, this new mode allows the
clients to connect directly over TLS, like it's done in HTTPS.

This is not an official standard yet, but it's reasonably common in
practice, and provides some advantages over the traditional submission
port.

The default port is 465, commonly used for this; chasquid defaults to
systemd file descriptor passing as for the other protocols (for now).
2017-04-10 19:59:04 +01:00
Alberto Bertogli
c4255933bd chasquid-util: Handle usernames without domain
Usernames must be of the form user@domain. When the domain is missing,
this patch makes chasquid-util emit a friendly error (instead of
crashing).
2017-04-10 19:48:35 +01:00
Alberto Bertogli
b86463f123 README: Mention Debian and Ubuntu packages 2017-03-25 09:39:30 +00:00
Alberto Bertogli
159aa97e8a Change the default MDA binary to "maildrop"
The current default is "procmail" for historical reasons, but the
program has been unmaintained for years and its use is not generally
advisable.

This patch changes the default MDA binary to "maildrop", which is a more
modern and reasonable MDA to use.

We keep the courier.Procmail name for now, as that's internal, but it
may be changed later.  Its documentation is updated to note that the
name is just for reference but it actually works with almost any binary.
2017-03-08 00:19:45 +00:00
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
f1b9d9e68a travis.yml: Add Go 1.8 to the test matrix 2017-03-01 01:03:00 +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
c2ea8a8ef0 test: Use our own netcat implementation :(
Netcat's behaviour after seeing EOF from stdin seems to not be very
portable or consistent, even under the same platform.

This has caused t-05-null_address to break recently under some
conditions, for example depending on the particular Debian version of
netcat-openbsd used, and the current situation is unclear.
See https://bugs.debian.org/854292 and https://bugs.debian.org/849192
for more details.

To stop depending on this brittle behaviour, this patch unfortunately
introduces a simple python3-based netcat for our tests to use.
2017-02-26 01:21:35 +00:00
Alberto Bertogli
700539876b smtp-check: Add a -skip_tls_check flag
This patch adds a -skip_tls_check flag, so smtp-check can still be used
from places where outgoing SMTP connections are blocked.
2017-01-04 13:37:26 -03: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
b1a29d8194 etc: Mention certificate requirements in the documentation
chasquid needs at least one certificate in order to start, to prevent
accidental misconfigurations.

This patch documents this in etc/chasquid/README, and while at it fixes
a minor terminology issue.

Thanks to Martin Ferrari for the bug report!
2016-11-22 20:43:07 +00:00
Alberto Bertogli
7b51ce725b chasquid: Ignore non-directories in certs/
We only care about directories within the certs/, but the code as-is
complains if there are files.

This patch makes the iteration skip non-directories entirely.

Thanks to Martin Ferrari for the bug report!
2016-11-22 20:39:19 +00:00
Alberto Bertogli
170aaaf490 chasquid-util: Create the domain directory when adding a user
When adding a user, chasquid-util should create the domain directory if
it doesn't exist, but currently doesn't do that.

This patch fixes this by adding the missing os.MkdirAll call.

Thanks to Martin Ferrari for the bug report!
2016-11-22 20:25:30 +00:00
Alberto Bertogli
279fff3cf8 systemd: Remove spaces around "="
systemd files should not have spaces around the "=", as apparently that
causes problems due to bad parsers.
2016-11-21 21:57:40 +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
db130639c2 Add configuration file for https://travis-ci.org/
This commit adds a .travis.yml which configures https://travis-ci.org/, a
continuous integration service.

It only builds and runs "go test" for now because their environment is
unfortunately too old to run the integration tests.
2016-11-04 00:20:26 +00:00
Alberto Bertogli
df673c63fb README: Add missing code block
One of the command sequences was not indented enough, so it appears as
text instead of code.

This patch fixes that by surrounding it with ``` to mark it explicitly
as a code block.
2016-11-03 10:21:13 +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
2da74c1758 docs: Add some documentation and a README 2016-11-03 00:51:59 +00:00
Alberto Bertogli
bcea74ca81 Add a license
This patch adds the Apache 2.0 license. Just a top level file for now,
but we may include the per-file boilerplate later if needed.
2016-11-03 00:51:59 +00:00
Alberto Bertogli
e4b789971d Makefile: Add targets for installation
This patch adds Makefile targets to install the binaries and the
skeleton configuration.
2016-11-03 00:51:59 +00:00
Alberto Bertogli
f43fd3d3cf gitignore: Fix binaries to only include top-level 2016-11-01 23:56:15 +00:00