26 Commits

Author SHA1 Message Date
Alberto Bertogli
5c2566c9b1 Fix non-constant format string in calls to Printf-like functions
In a few places, we call Printf-like functions, but for the format we
use either non-format messages (which is not tidy, but okay), or
variable messages (which can be problematic if they contain %-format
directives).

The patch fixes the calls by either moving to Print-like functions, or
using `Printf("%s", message)` instead.

These were found by a combination of `go vet` (which complains about
"non-constant format string in call"), and manual inspection.
2025-10-24 12:34:58 +01:00
Alberto Bertogli
9999a69086 aliases: Implement "via" aliases
This patch implements "via" aliases, which let us explicitly select a
server to use for delivery.

This feature is useful in different scenarios, such as a secondary MX
server that forwards all incoming email to a primary.

For now, it is experimental and the syntax and semantics are subject to
change.
2025-04-12 23:23:21 +01:00
Alberto Bertogli
e6a9410377 Exit if there's an error reading users/aliases files on startup
Today, when starting up, if there's an error reading the users or
aliases files, we only log but do not exit. And then those files will
not be attempted to be read on the periodic reload.

We also treat "file does not exist" as an error for users file, but not
aliases file, resulting in inconsistent behaviour between the two.

All of this makes some classes of problems (like permission errors) more
difficult to spot and troubleshoot. For example,
https://github.com/albertito/chasquid/issues/55.

So this patch makes errors reading users/aliases files on startup a
fatal error, and also unifies the "file does not exist" behaviour to
make it not an error in both cases.

Note that the behaviour on the periodic reload is unchanged: treat these
errors as fatal too. This may be changed in future patches.
2024-05-10 12:09:53 +01:00
Alberto Bertogli
76a72367ae dkim: Implement internal dkim signing and verification
This patch implements internal DKIM signing and verification.
2024-03-12 20:43:21 +00: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
Alberto Bertogli
3ebe5c5173 Replace uses of ioutil
ioutil package was deprecated in Go 1.16, replace all uses with their
respective replacements.

This patch was generated with a combination of `gofmt -r`, `eg`, and
manually (for `ioutil.ReadDir`).
2022-11-12 20:06:35 +00:00
Alberto Bertogli
90d385556f testlib: Add GenerateCert function
This patch moves the GenerateCert function from the smtpsrv tests to the
common testlib, so it can be used by other tests in the future.
2021-10-25 12:41:24 +01:00
Alberto Bertogli
85305f4bd9 smtpsrv: Close the connection after 3 errors (lowering from 10)
Today, we close the connection after 10 errors. While this is fine for
normal use, it is unnecessarily large.

Lowering it to 3 helps with defense-in-depth for cross-protocol attacks
(e.g. https://alpaca-attack.com/), while still being large enough for
useful troubleshooting and normal operation.

As part of this change, we also remove the AUTH-specific failures limit,
because they're covered by the connection limit.
2021-06-11 10:34:20 +01:00
Alberto Bertogli
d3396ace0b smtpsrv: Return a temporary error when we fail to check if a user exists
When we fail to check if a user exists, we currently return a permanent
error, which can be misleading and also make things more difficult to
troubleshoot.

This patch makes chasquid return a temporary error in that case.

Thanks to Thor77 (thor77@thor77.org) for suggesting this change.
2021-05-30 00:39:24 +01:00
Alberto Bertogli
d83c1dc591 smtpsrv: Fix error code on transient authentication issues
When we can't authenticate due to a transient issue, for example if we
rely on Dovecot and it is not responding, we should use a differentiated
error code to avoid confusing users.

However, today we return the same error code as when the user enters the
wrong password, which could confuse users as their MUA might think their
credentials are no longer valid.

This patch fixes the issue by returning a differentiated error code in
that case, as per RFC 4954.

Thanks to Max Mazurov (fox.cpp@disroot.org) for reporting this problem.
2020-05-23 01:05:12 +01: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
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
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
e7309a2c7b smtpsrv: Send enhanced status codes
SMTP supports enhanced status codes, which help with
internationalization and accessibility in cases where protocol errors
make their way to the users.

This patch makes chasquid include these extended status codes in the
corresponding replies, as well as advertising support in the EHLO reply.

Main references:
- RFC 3463 (https://tools.ietf.org/html/rfc3463)
- RFC 2034 (https://tools.ietf.org/html/rfc2034)
- SMTP Enhanced Status Codes Registry
  (https://www.iana.org/assignments/smtp-enhanced-status-codes/smtp-enhanced-status-codes.xhtml)
2019-01-10 15:44:25 +00:00
Alberto Bertogli
4db9ffec09 Code style improvements
This patch contains some minor code style improvements, to leave the
linter happier and generally follow best practices in some areas where
things snuck through.
2018-12-01 11:58:50 +00: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
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
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
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
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