1
0
mirror of https://blitiri.com.ar/repos/chasquid synced 2025-12-17 14:37:02 +00:00
Commit Graph

546 Commits

Author SHA1 Message Date
Alberto Bertogli
a14ba106b1 docs: Add CVE-2023-52354 links to the release notes
The SMTP smuggling vulnerability fixed in 1.13 (and 1.11.1) has been
given a CVE number: CVE-2023-52354
(https://nvd.nist.gov/vuln/detail/CVE-2023-52354).

This patch adds a link to it in the release notes, for ease of reference.
2024-02-05 00:04:50 +00:00
Ernesto Alfonso
36c5139da4 Skip non-directories in the domains/ directory
This prevents chasquid from attempting to look for certs under a
non-directory, e.g. `/etc/chasquid/domains/.gitignore/certs`.

Amended-by: Alberto Bertogli <albertito@blitiri.com.ar>
  Adjusted commit message, applied `go fmt`.
2024-02-05 00:04:37 +00:00
Alberto Bertogli
bb8f16fb97 docs: Add 1.11.1 to the release notes
chasquid v1.11.1 was released on 2023-12-26 with a backport of the
security fixes from 1.13.

This was requested by users of Debian stable, who are on 1.11.
2024-01-21 11:37:40 +00:00
Alberto Bertogli
e28f346313 docs: v1.13 release notes v1.13 v1.13.0 2023-12-24 21:56:06 +00:00
Alberto Bertogli
a996106eee smtpsrv: Strict CRLF enforcement in DATA contents
The RFCs are very clear that in DATA contents:

> CR and LF MUST only occur together as CRLF; they MUST NOT appear
> independently in the body.

https://www.rfc-editor.org/rfc/rfc5322#section-2.3
https://www.rfc-editor.org/rfc/rfc5321#section-2.3.8

Allowing "independent" CR and LF can cause a number of problems.

In particular, there is a new "SMTP smuggling attack" published recently
that involves the server incorrectly parsing the end of DATA marker
`\r\n.\r\n`, which an attacker can exploit to impersonate a server when
email is transmitted server-to-server.

https://www.postfix.org/smtp-smuggling.html
https://sec-consult.com/blog/detail/smtp-smuggling-spoofing-e-mails-worldwide/

Currently, chasquid is vulnerable to this attack, because Go's standard
libraries net/textproto and net/mail do not enforce CRLF strictly.

This patch fixes the problem by introducing a new "dot reader" function
that strictly enforces CRLF when reading dot-terminated data, used in
the DATA input processing.

When an invalid newline terminator is found, the connection is aborted
immediately because we cannot safely recover from that state.

We still keep the internal representation as LF-terminated for
convenience and simplicity.

However, the MDA courier is changed to pass CRLF-terminated lines, since
that is an external program which could be strict when receiving email
messages.

See https://github.com/albertito/chasquid/issues/47 for more details and
discussion.
2023-12-24 10:43:27 +00:00
Alberto Bertogli
e03594a2c7 test: Make mail_diff more strict
This patch makes mail_diff more strict in its parsing, to ensure we
catch any encoding issues that may otherwise be masked by the default
compatibility policy.
2023-12-23 14:10:16 +00:00
Alberto Bertogli
c4c330d7a4 test: Verify mailbox delivery in minor dialogs test
The minor dialogs test covers some very specific SMTP exchanges, and
some of those include delivering email.

Today, we don't verify the final mailbox, we just check the SMTP
exchange. However, it can be very useful for some of the tests to do
end-to-end checking of the final mailbox.

This patch implements that ability in the test itself, and on the
(currently only) email delivering dialog.

Subsequent patches that introduce new tests will make use of this
feature.
2023-12-23 13:21:27 +00:00
Alberto Bertogli
0c02bfbe76 modules: Update Go dependencies 2023-12-21 15:41:20 +00:00
Alberto Bertogli
83ae4c3478 userdb: Add support for receive-only users
Some use cases, like receive-only MTAs, need domain users for receiving
emails, but have no real need for passwords since they will never use
submission.

Today, that is not supported, and those use-cases require the
administrator to come up with a password unnecessarily, adding
complexity and possibly risk.

This patch implements "receive-only users", which don't have a valid
password, thus exist for the purposes of delivering mail, but always
fail authentication.

See https://github.com/albertito/chasquid/issues/44 for more details and
rationale.

Thanks to xavierg who suggested this feature on IRC.
2023-12-03 11:59:26 +00:00
Alberto Bertogli
dbff2f0455 Reject empty listening addresses
Using an empty listening address will result in chasquid listening on a
random port, which is a dangerous misconfiguration.

That is most likely done to prevent it from listening at all.

To prevent this misconfiguration, explicitly reject empty listening
addresses early and with a warning, so there is no ambiguity.

Users can still prevent chasquid from listening by just commenting out
the entry in the config (and not passing any systemd file descriptors).

See https://github.com/albertito/chasquid/issues/45 for more details and
discussion, including alternatives considered.

Thanks to xavierg who reported this via IRC.
2023-12-02 15:08:09 +00:00
Alberto Bertogli
d93d7cae10 config: Quote strings when logging the configuration
When logging the configuration, we currently don't quote the string
values, which can make whitespace-induced problems difficult to identify
and troubleshoot.

This patch changes the formatting to always quote string values when
logging the configuration.
2023-12-02 15:01:31 +00:00
Ernesto Alfonso
a0f09308ed docker/add-user.sh: Don't crash on updating when there is a single user
When a single dovecot user exists and their password is being updated via
docker/add-user.sh, the `grep -v` command intended to remove the user's
old password will not match any lines and exit with error code 1, causing
the entire script to fail.

This patch fixes it by replacing the if-grep logic with a simpler sed
invocation.

https://github.com/albertito/chasquid/pull/43

Amended-by: Alberto Bertogli <albertito@blitiri.com.ar>
  Minor edits to the commit message.
2023-10-29 22:28:08 +00:00
Ernesto Alfonso
0ce84a3b5d docker/add-user.sh: Support getting email and password from env variables
This patch extends docker/add-user.sh to support getting the email and
password from environment variables.

That way, docker/add-user.sh can be used in scripts.

https://github.com/albertito/chasquid/pull/43

Amended-by: Alberto Bertogli <albertito@blitiri.com.ar>
  Minor edits to the commit message.
2023-10-29 22:25:35 +00:00
Alberto Bertogli
6713fb7aef modules: Update Go dependencies 2023-10-27 18:00:23 +01:00
Ernesto Alfonso
359d45a3de docker: Fix using a domain directory path as a domain name
There is a bug causing an invalid config in the generated
/etc/dovecot/auto-ssl.conf, e.g.:

ssl_cert = </etc/letsencrypt/live//etc/letsencrypt/live/mail.grouplok.com/fullchain.pem
ssl_key = </etc/letsencrypt/live//etc/letsencrypt/live/mail.grouplok.com/privkey.pem

This patch fixes it by using the domain name instead of the path, which
matches the original intent.

https://github.com/albertito/chasquid/pull/42

Amended-by: Alberto Bertogli <albertito@blitiri.com.ar>
  Minor edits to the commit message.
2023-10-27 10:48:34 +01:00
Alberto Bertogli
27fd7e7220 docs: v1.12 release notes v1.12 2023-10-07 16:53:58 +01:00
Alberto Bertogli
8cc42df249 modules: Update Go dependencies (again)
This patch does a general pass updating dependencies to their latest
versions.
2023-10-07 16:53:58 +01:00
Alberto Bertogli
f5d8c68a39 test: Add the embedded aliases file to the fuzz corpus
This patch adds the embedded aliases file to the fuzz corpus, because it
is trivial to do so, and is a reasonable seed which will be naturally
adjusted over time as the package evolves (as it happened in recent
commits).
2023-10-07 16:41:26 +01:00
Alberto Bertogli
5cdbd9ff6e Fix documentation/comment typos
This patch fixes a variety of typos in documentation and comments, found
by running `codespell`.
2023-10-07 12:41:57 +01:00
Alberto Bertogli
43e98e08a8 test: Minor bash style fixes to t-04-aliases
This patch contains minor bash style fixes to test/t-04-aliases, for
readability and consistency.
2023-10-07 12:41:57 +01:00
Alberto Bertogli
669bccc13f modules: Update Go dependencies
This patch does a general pass updating dependencies to their latest
versions.
2023-10-04 15:43:41 +01:00
Alberto Bertogli
a80051657a docs/man: Auto-generate markdown manpages
This patch adds auto-generation of markdown manpages, for ease of
reference in other documents and links.
2023-10-04 00:31:14 +01:00
Alberto Bertogli
8ded1f6f5e Auto-format protobuf files
This patch runs clang-format on the protobuf files, and also adds a
Makefile target for auto-formatting code (Go and protobuf) for
convenience.
2023-10-03 23:34:23 +01:00
Alberto Bertogli
d57037273c localrpc test: Don't call t.Fatal from a goroutine
The testing package does not allow t.Fatal to be called from a different
goroutine; however, we do that if the testing server fails listen or
accept connections.

Since that is unexpected and rare, this patch turns those calls into
panics.
2023-10-03 23:32:30 +01:00
Alberto Bertogli
74e7c96031 aliases: Drop characters when parsing, and support suffix-specific aliases
Today, when a user sets an alias with drop characters and/or suffixes,
those go unused, since we always "clean" addresses before alias
resolution.

This results in unexpected and surprising behaviour, and it's not
properly documented either.

This patch resolves this unexpected behaviour as follows:

- Drop characters are ignored, both at parsing time and at lookup time.
- Lookups are done including the suffixes first, and if that results in
  no matches, they are retried without suffixes.

This results in aliases working more intuitively for the most common use
cases: of users wanting to have different aliases for specific suffixes,
and not having to care for drop characters.

Hooks can be used to get different behaviour if needed, since the first
lookup is done with the address as-is.

Thanks to znerol@ (lo+github@znerol.ch) for reporting this, and the
discussion on how to fix it, in
https://github.com/albertito/chasquid/issues/41.
2023-09-24 09:33:01 +01:00
Alberto Bertogli
d086fbbb97 aliases: Make parsing functions methods of the resolver
Today, the parsing functions are stand-alone since they don't need
anything from the resolver.

But in future patches, that will change.

In anticipation of that, move those functions to be methods of the
resolver.
2023-09-24 09:32:32 +01:00
Alberto Bertogli
8bbb6118e5 aliases: Exists does not need to return the "clean" address
The aliases.Resolver.Exists function currently returns the "clean"
address (with the drop characters and suffixes removed), which is relied
upon in its only caller.

That, however, makes the logic more difficult to follow, hiding some
of the address manipulation behind what should be a read-only check.

So this patch reorganizes that code a little bit, removing the
"cleaning" of the address as part of Exists, and making it explicit when
needed instead.

This patch does not have any user-visible change in behaviour, it is
just internal reorganization.

This is in preparation for further patches which will improve the
handling of some aliases corner cases.
2023-09-24 09:32:32 +01:00
Alberto Bertogli
dc10031e1c docs: Reflect chasquid-util alias-resolve changes
Since commit e6c6df45, `chasquid-util alias-resolve` talks to the server
and returns authoritative answers.

This patch updates docs/aliases.md to reflect that, which was missed in
the original set of changes.
2023-09-24 09:32:32 +01:00
Alberto Bertogli
9d7842878b test: Make t-04-aliases fail on unexpected mail
Today we check the aliases deliver mail to the expected locations, but
we don't fail if there are unexpected deliveries.

Doing so can help catch bugs (including test bugs), so this patch
implements that.

In addition, fix two of the tests that were printing on error, but not
causing the tests to fail (which was the original intention).
2023-09-24 09:08:23 +01:00
Alberto Bertogli
f51b449c69 chasquid: Move the certificate loading logic in a separate function
This patch moves the top-level certificate loading logic out of main and
into a separate function.

This is only for readability and consistency with how we handle domains
(which have a similar structure already). There are no logic changes.
2023-09-17 10:58:25 +01:00
Alberto Bertogli
b9e222f6eb chasquid: Remove unnecessary logging on loading aliases and users on startup
When starting up, for each domain we parse aliases and users files (if
they exist).

Today we print a line for each, which gets quite verbose and doesn't
offer much useful information.

This patch adjusts that logic so that we only print errors (unless a
file does not exist, which is a normal case).

This also improves the scenario where chasquid does not have permissions
to access the users file: before this patch, that would fail silently,
but with this patch we show the correct error.

While at it, make the "Loading" messages consistent with each other, for
readability.
2023-09-17 10:54:49 +01:00
Alberto Bertogli
2c02f0d128 test: Make t-20-bad_configs less flaky due to asynchronous logging
The t-20-bad_configs test can sometimes have false positives because
the last line recorded in the log isn't always the one causing the
failure, due to asynchronous logging and in particular in combination
with coverage tests (which alter the os.Exit behaviour subtly).

This patch fixes that by having the tests look at the last 4 lines of
output instead. This is not super pretty, but it should be good enough
to cover for any timing issues that arise in these particular tests.
2023-09-02 14:12:36 +01:00
Alberto Bertogli
888b2df4c1 Handle symlinks under the certs/ directory
Currently, if the `certs/` directory has a symlink inside, we skip it.
That is not really intended, it's an unfortunate side-effect of skipping
regular files.

To fix this, this patch adjusts the logic to only ignore regular files
instead. It also adds a message when a directory is skipped, to make it
easier to debug permission issues.

Thanks to @erjoalgo for reporting this in
https://github.com/albertito/chasquid/pull/39, and providing an
alternative patch!
2023-09-02 13:58:24 +01:00
Alberto Bertogli
47535651d2 chasquid-util: Remove aliases-add subcommand
The aliases-add subcommand was added before aliases hooks were
implemented and polished, it is undocumented, and the implementation is
nowadays a bit brittle, has some rough edges, and adds significant code
complexity to chasquid-util.

AFAIK nobody is using it either (checked with some specific folks
directly, and it's not very discoverable either).

For all those reasons, this patch removes it.
2023-08-10 00:12:56 +01:00
Alberto Bertogli
57ee3733f4 modules: Update Go modules
This patch does a general pass updating dependencies to their latest
versions.
2023-07-30 13:21:07 +01:00
Alberto Bertogli
e6c6df457d chasquid-util: Use server for aliases-resolve and domaininfo-remove
This patch makes chasquid-util's aliases-resolve and domaininfo-remove
commands talk to the chasquid server (via the new localrpc server).

For aliases-resolve, currently has fairly hacky logic which reimplements
a bunch of the servers', and is also incomplete because it does not
support hooks.

In this patch we fix that by having it talk to the server, where we get
authoritative responses and have no issues with aliases hooks. This
resolves https://github.com/albertito/chasquid/issues/18.

For domaininfo-remove, currently its implementation is also very hacky
since it manipulates files behind the servers' back and without even
using the internal library.

In this patch we fix that by doing the operation through the server,
avoiding the need for those hacks, and also remove the need to manually
reload the server afterwards.
2023-07-30 13:21:07 +01:00
Alberto Bertogli
ddd1b6d96e chasquid: Run a localrpc server
This patch makes chasquid run a localrpc server, exporting two methods:
alias resolve, and domaininfo clear.

They will be used by chasquid-util in later patches.
2023-07-30 13:21:07 +01:00
Alberto Bertogli
360ac13a73 localrpc: Add a package for local RPC over UNIX sockets
This patch adds a new package for doing local lightweight RPC calls over UNIX
sockets. This will be used in later patches for communication between chasquid
and chasquid-util.
2023-07-30 13:21:07 +01:00
Alberto Bertogli
764c09e94d domaininfo: Add a Clear method to clear information for a given domain
This patch adds a Clear method to the domaininfo database, which removes
information for the given domain.

This can be used to manually make the server forget about a domain, in
case there are operational reasons to do so.

Today, this is done via chasquid-util (which removes the backing file),
but that is hacky, and this is part of replacing it with a cleaner
implementation.
2023-07-30 11:34:27 +01:00
Alberto Bertogli
ac1c849a27 docs: Document how to report a security issue
Some systems, like GitHub, can use `docs/SECURITY.md` to inform users on
how to report security issues.

This patch adds one to the tree. It is not linked explicitly in mkdocs
because the same information is already covered in the doc index and
README already.
2023-07-28 10:05:15 +01:00
Alberto Bertogli
2e279de304 github: Run coverage tests
This patch adds a job to the docker workflow to run coverage tests, and
upload the results to coveralls.
2023-07-28 10:05:15 +01:00
Alberto Bertogli
a3f7914e29 sts: Remove unused struct member
There is no synchronization needed in the sts cache, because changes are
handled atomically on-disk and there is no in-memory persistence.
2023-07-28 10:05:15 +01:00
Alberto Bertogli
2b7e33a615 domaininfo: Do not reload the database periodically
It is not expected that the user modifies the domaininfo database behind
chasquid's back, and reloading it can be somewhat expensive.

So this patch removes the periodic reload, and instead makes it triggered
by SIGHUP so the user can trigger a reload manually if needed.
2023-07-28 10:05:15 +01:00
znerol
ad0dbb9cda smtp-check: Add flag to specify local name
Some MTAs reject client connections unless the local name (used in the
HELO/EHLO command) looks like an FQDN. Currently, smtp-check always uses
`localhost`, which does not look like an FQDN.

This patch adds a command line flag to smtp-check to specify the
local name to be used.

Fixes https://github.com/albertito/chasquid/issues/37.

Amended-by: Alberto Bertogli <albertito@blitiri.com.ar>
  Minor edits to the commit message, adjust flag name, go fmt.
2023-07-16 10:03:50 +01:00
Alberto Bertogli
9e8452520a docs: Update badge/link to the CI status
The current badge, which covers all the branch checks doesn't work, it
always says "pending".

This patch replaces it with the gotest workflow status. It is much more
narrow, but at least it works and gives a decent indication of the
testing status.
2023-05-24 22:18:12 +01:00
Alberto Bertogli
01a6d088e2 test: Add a set of tests for handling bad/invalid configs
This patch adds a set of tests to validate chasquid's handling of bad
and invalid configurations, to make sure we fail as expected.
2023-05-17 00:44:54 +01:00
Alberto Bertogli
0c9d1536db docs: Update tests.md to reflect coverage changes, and add links
This patch updates tests.md to reflect the recent changes around
coverage testing, specifically we no longer have coverage issues with
fatal/non-zero exits, so remove that section from the docs.

Also while at it, add links to the software we reference, for
convenience.
2023-05-16 10:50:26 +01:00
Alberto Bertogli
e85ad54a73 Regenerate auto-generated files
This patch regenerates the auto-generated files.

There are no significant changes, the protobuf just get an updated
comment due to protoc version change, but it is just informational.

Two new TLS ciphers are added, matching the new IANA assignments.
2023-03-03 11:24:40 +00:00
Alberto Bertogli
fd9c6a748b courier/smtp: Retry over plaintext on STARTTLS errors
When the SMTP courier gets an error on STARTTLS (either because the
command itself failed, or because there was a low-level TLS negotiation
error), today we just fail that attempt.

This can cause messages to never be delivered if the underlying reason
is a server misconfiguration (e.g. a server certificate that Go cannot
parse). This is quite rare in practice, but it can happen.

To prevent this situation, this patch adds logic so that the SMTP
courier retries over plaintext when STARTTLS fails.

This is still subject to security level checks, so this type of failures
cannot be used to downgrade connections to domains we successfully
established a TLS connection previously.

Note that certificate validation issues are NOT included in this
type of failure, so they will not trigger a retry. The certificate
validation handling is unchanged by this patch.
2023-03-03 09:51:48 +00:00
Alberto Bertogli
1927e15ea2 docs: v1.11 release notes v1.11 2023-02-19 16:20:50 +00:00