Commit graph

241 commits

Author SHA1 Message Date
Mechiel Lukkien
40163bd145
implement storing non-system/well-known flags (keywords) for messages and mailboxes, with imap
the mailbox select/examine responses now return all flags used in a mailbox in
the FLAGS response. and indicate in the PERMANENTFLAGS response that clients
can set new keywords. we store these values on the new Message.Keywords field.
system/well-known flags are still in Message.Flags, so we're recognizing those
and handling them separately.

the imap store command handles the new flags. as does the append command, and
the search command.

we store keywords in a mailbox when a message in that mailbox gets the keyword.
we don't automatically remove the keywords from a mailbox. there is currently
no way at all to remove a keyword from a mailbox.

the import commands now handle non-system/well-known keywords too, when
importing from mbox/maildir.

jmap requires keyword support, so best to get it out of the way now.
2023-06-24 00:24:43 +02:00
Mechiel Lukkien
afefadf2c0
in websocket data copying code, wait for other goroutine to stop before changing the connection
found while running tests
2023-06-24 00:14:14 +02:00
Mechiel Lukkien
459317097b
fix typo's and old reference 2023-06-22 21:27:52 +02:00
Mechiel Lukkien
8096441f67
new feature: when delivering messages from the queue, make it possible to use a "transport"
the default transport is still just "direct delivery", where we connect to the
destination domain's MX servers.

other transports are:

- regular smtp without authentication, this is relaying to a smarthost.
- submission with authentication, e.g. to a third party email sending service.
- direct delivery, but with with connections going through a socks proxy. this
  can be helpful if your ip is blocked, you need to get email out, and you have
  another IP that isn't blocked.

keep in mind that for all of the above, appropriate SPF/DKIM settings have to
be configured. the "dnscheck" for a domain does a check for any SOCKS IP in the
SPF record. SPF for smtp/submission (ranges? includes?) and any DKIM
requirements cannot really be checked.

which transport is used can be configured through routes. routes can be set on
an account, a domain, or globally. the routes are evaluated in that order, with
the first match selecting the transport. these routes are evaluated for each
delivery attempt. common selection criteria are recipient domain and sender
domain, but also which delivery attempt this is. you could configured mox to
attempt sending through a 3rd party from the 4th attempt onwards.

routes and transports are optional. if no route matches, or an empty/zero
transport is selected, normal direct delivery is done.

we could already "submit" emails with 3rd party accounts with "sendmail". but
we now support more SASL authentication mechanisms with SMTP (not only PLAIN,
but also SCRAM-SHA-256, SCRAM-SHA-1 and CRAM-MD5), which sendmail now also
supports. sendmail will use the most secure mechanism supported by the server,
or the explicitly configured mechanism.

for issue #36 by dmikushin. also based on earlier discussion on hackernews.
2023-06-16 18:57:05 +02:00
Mechiel Lukkien
2eecf38842
unbreak the subcommands that talk to the mox instance of the ctl socket
broken on may 31st with the "open tls keys as root" change, 70d07c5459, so
broken in v0.0.4, not in v0.0.3
2023-06-16 13:27:27 +02:00
Mechiel Lukkien
f73125cbcd
restore checking integration_test.go with go vet 2023-06-16 12:55:57 +02:00
Mechiel Lukkien
e81ed7af26
in DSN, don't add a comment with a nil IP address if we don't have an IP 2023-06-16 09:55:45 +02:00
Mechiel Lukkien
b190a2cda8
mention good hosting providers may initially block outgoing smtp too 2023-06-12 16:35:03 +02:00
Mechiel Lukkien
d4d3f8ce92
add FAQ about the common misconceptation that you cannot run your own email server nowadays 2023-06-12 16:25:35 +02:00
Mechiel Lukkien
c561d7452b
unbreak "mox localserve"
i broke it with 70d07c5459, so broken in v0.0.4, not in v0.0.3
2023-06-12 14:59:40 +02:00
Mechiel Lukkien
d2f7d59fce
for dns resolve errors likely due to a missing name server in /etc/resolv.conf, point user to man page of systemd-resolved, the likely cause
it seems linux machines with systemd-resolved don't always set up
/etc/resolv.conf correctly. there may be no "nameserver" entry, causing Go's
net resolver to fallback to 127.0.0.1 and ::1. Systemd-resolved is listening on
127.0.0.53, so users will likely get a "connection refused". So point users to
the systemd-resolved manual page.

for issue #38 by ArnoSen
2023-06-12 14:53:07 +02:00
Mechiel Lukkien
64ac9872a4
in quickstart, if the host name resolves to a loopback IP, warn about it as it will likely prevent email delivery to local accounts
would have helped for issue #37, thanks @dmikushin for reporting
2023-06-12 12:19:20 +02:00
Mechiel Lukkien
0187fa0394
tweak time format for added date headers
seconds are useful, leading zeros for "day" not so much
2023-06-04 21:04:10 +02:00
Mechiel Lukkien
41167d6393
regenerate keys/certs for integration tests with expiration far in the future
don't want to have expiring tests...
2023-06-04 20:43:19 +02:00
Mechiel Lukkien
05fd5c6947
add automated test for quickstart
with tls with acme (with pebble, a small acme server for testing), and with
pregenerated keys/certs.

the two mox instances are configured on their own domain. we launch a separate
test container that connects to the first, submits a message for delivery to
the second. we check if the message is delivered with an imap connection and
the idle command.
2023-06-04 20:38:10 +02:00
Mechiel Lukkien
e53b773d04
fix bug with dkim signing messages without Date or Message-Id header
we were adding the missing date and/or message-id header, but didn't sign it.
and the default dkim signing config is to (over)sign those headers. so that was
causing errors with bad signatures.

found while setting up automated tests for quickstart, while sending a very
basic message between a fresh install.
2023-06-04 20:32:18 +02:00
Mechiel Lukkien
c9a846d019
more logging around smtp and mtasts tls connections
i wondered why self-signed mtasts certs didn't result in delivery failure. it's
because it was a first-time request of the mtasts policy (clean test
container). and for that case it means mtasts should be ignored.
2023-06-04 17:55:55 +02:00
Mechiel Lukkien
5a4f35ad5f
fix delivery from/to smtp addresses with double quotes
found while adding tests for smtp and imap for address with empty double (double
quoted) localparts.
2023-06-03 15:29:18 +02:00
Mechiel Lukkien
77d78191f8
more helpful error message when the queue tries to deliver a message but the remote host is not listed in the mta-sts policy
based on questions on irc by Nemain where this better error message would
probably have made the problem easier to find and fix.
2023-06-01 16:23:36 +02:00
Mechiel Lukkien
cafbfc5fdf
tweaks to backup & verifydata tool to make a typical backup+verifydata produce no output
for easy use in a crontab
2023-06-01 11:34:28 +02:00
Mechiel Lukkien
d25131f2f2
add missing check for err variable in test 2023-05-31 21:57:46 +02:00
Mechiel Lukkien
713d781bad
log a consistent log line for failed authentication attempts, with the remote ip
so external tools (like fail2ban) can monitor the logs and block ip's of bots.

for issue #30 by inigoserna, though i'm not sure i interpreted the suggestion correctly.
2023-05-31 20:39:00 +02:00
Mechiel Lukkien
70d07c5459
open tls keys/certificate as root, pass fd's to the unprivileged child process
makes it easier to use tls keys/certs managed by other tools, with or without
acme. the root process has access to open such files. the child process reads
the key from the file descriptor, then closes the file.

for issue #30 by inigoserna, thanks!
2023-05-31 14:09:53 +02:00
Mechiel Lukkien
dd0cede4f9
after a logout command, actually close the connection
reported by inigoserna in issue #30, thanks!
2023-05-31 10:31:25 +02:00
Mechiel Lukkien
5b8efcc1d9
move "how do i upgrade"-question to just below "how do i stay up to date" question 2023-05-31 10:30:34 +02:00
Mechiel Lukkien
0971700f6c
add ios push mail on not-soon-todo list
someone asked at the the recent golang rotterdam meetup if this would be added.
i looked into it, and it requires implementing an imap extension
XAPPLEPUSHSERVICE (not documented, but apple published modified dovecot
software for macos server that implemented it). to send push notifications to
the ios mail app, you need a APNS certificate. the tutorials online explain you
have to purchase macos server (a deprecated product) and extract the APNS
certificate. the certificate is valid for one year. i'm not sure it still
works, and it feels like it could stop working at any moment. but implementing
it seems doable.
2023-05-31 10:24:48 +02:00
Mechiel Lukkien
259928ab62
add reverse proxying websocket connections
if we recognize that a request for a WebForward is trying to turn the
connection into a websocket, we forward it to the backend and check if the
backend understands the websocket request. if so, we pass back the upgrade
response and get out of the way, copying bytes between the two. we do log the
total amount of bytes read from the client and written to the client. if the
backend doesn't respond with a websocke response, or an invalid one, we respond
with a regular non-websocket response. and we log details about the failed
connection, should help with debugging and any bug reports.

we don't try to parse the websocket framing, that's between the client and the
backend.  we could try to parse it, in part to protect the backend from bad
frames, but it would be a lot of work and could be brittle in the face of
extensions.

this doesn't yet handle websocket connections when a http proxy is configured.
we'll implement it when someone needs it. we do recognize it and fail the
connection.

for issue #25
2023-05-30 22:11:31 +02:00
Mechiel Lukkien
aca64828bd
we now have an index on dkimdomains, remove the todo 2023-05-26 20:49:13 +02:00
Mechiel Lukkien
aad5a5bcb9
add a "backup" subcommand to make consistent backups, and a "verifydata" subcommand to verify a backup before restoring, and add tests for future upgrades
the backup command will make consistent snapshots of all the database files. i
had been copying the db files before, and it usually works. but if the file is
modified during the backup, it is inconsistent and is likely to generate errors
when reading (can be at any moment in the future, when reading some db page).
"mox backup" opens the database file and writes out a copy in a transaction.
it also duplicates the message files.

before doing a restore, you could run "mox verifydata" on the to-be-restored
"data" directory. it check the database files, and compares the message files
with the database.

the new "gentestdata" subcommand generates a basic "data" directory, with a
queue and a few accounts. we will use it in the future along with "verifydata"
to test upgrades from old version to the latest version. both when going to the
next version, and when skipping several versions. the script test-upgrades.sh
executes these tests and doesn't do anything at the moment, because no releases
have this subcommand yet.

inspired by a failed upgrade attempt of a pre-release version.
2023-05-26 19:26:51 +02:00
Mechiel Lukkien
753ec56b3d
make "mailbox" parameter to unlisted command "bumpuidvalidity" optional, to update the uidvalidity for all mailboxes
useful after a database restore.
2023-05-22 18:11:42 +02:00
Mechiel Lukkien
d18983d9a6
add github workflow to build & test, exporting a coverage file 2023-05-22 18:01:21 +02:00
Mechiel Lukkien
dcc051e149
for fuzzing the imapserver and smtpserver use different config files than regular tests
otherwise they cannot be running at the same time, they could overwrite each
other's files.
2023-05-22 15:37:03 +02:00
Mechiel Lukkien
1f5ab1b795
fix language in comments
found through goreportcard.com
2023-05-22 15:04:06 +02:00
Mechiel Lukkien
b0623e6038
in queue.Drop, to drop a message from the outgoing queue, not only remove it from the database, but also its contents from the file system 2023-05-22 15:03:23 +02:00
Mechiel Lukkien
88fd775ec4
if we encounter an error fetching an mta-sts policy as part of a delivery attempt, properly continue with delivery with strict tls checking 2023-05-22 14:46:20 +02:00
Mechiel Lukkien
e81930ba20
update to latest bstore (with support for an index on a []string: Message.DKIMDomains), and cyclic data types (to be used for Message.Part soon); also adds a context.Context to database operations. 2023-05-22 14:40:36 +02:00
Kohei Watanabe
f6ed860ccb
Fixed MTASTSHTTPS.NonTLS option (#29)
AutoconfigHTTPS.NonTLS option was being used.
Fixed to use MTASTSHTTPS.NonTLS option.
2023-05-03 16:26:04 +02:00
Mechiel Lukkien
70ab9a7d4c
tweak alerting rule to include that it is about authentication rate limiting 2023-05-01 14:21:02 +02:00
Mechiel Lukkien
c1753b369d
in smtpserver, accept delivery to postmaster@<hostname>, and also postmaster@ addresses for domains that don't have a postmaster address configured. 2023-04-24 12:04:46 +02:00
Mechiel Lukkien
74dab5fc39
fix sending to address where the domain does not have an mx record (but where we should connect directly to the host, or follow cname records)
such deliveries would fail because a canceled "context" was reused, so the dns
lookups would fail.

the tests didn't catch it before because they ignored their context parameters.
2023-04-24 10:34:19 +02:00
Mechiel Lukkien
1f4df30019
remove debug print 2023-04-24 10:06:59 +02:00
Mechiel Lukkien
517fb31212
clear updating.txt for release 2023-04-22 07:52:42 +02:00
Mechiel Lukkien
b3f3c0a056
in smtpclient, when delivering with pipelining, don't return a unhelpful read error when the remote server closes the connection early after writing an error response
e.g. when outlook.com puts your IP on a blocklist, it will respond with 550 to
MAIL FROM, then closes the connection (without responding to the remaining
commands). we were reading the 550 response, not yet acting on it, then reading
the response to RCPT TO. that read failed, and we would return that error. now,
we will properly return the 550 (permanent error, instead of the temporary read
error) from the first MAIL FROM (but we do still always try to read the
response for RCPT TO and DATA).
2023-04-20 22:29:18 +02:00
Mechiel Lukkien
0b364862ed
add link to screenshots
the screenshots are not in the git repo, they may change quite a bit and are
larger binary blobs. i don't want to make the repo too big (the code with its
dependencies is already pretty big!).

the website with the screenshots is in github.com/mjl-/mox.

for github issue #26
2023-04-20 16:47:32 +02:00
Mechiel Lukkien
dae73eb32d
update golang.org/x dependencies 2023-04-20 15:07:24 +02:00
Mechiel Lukkien
6eff832d09
fix fuzzing imapserver by not triggering the rate limiter 2023-04-20 14:58:05 +02:00
Mechiel Lukkien
08eb1a5472
in store/, change functions from calling panic to returning errors
this is a library package, errors should be explicit. callers had to be careful
when calling these "X" functions. now it's explicit.
2023-04-20 14:16:56 +02:00
Mechiel Lukkien
936a0d5afe
bugfix: when dkim-signing submitted messages, use the domain from the "message from header" instead of "smtp mail from"
dmarc verifiers will only accept a dkim signature if the domain the message From
header matches the domain of the signature (i.e. it is "aligned").

i hadn't run into this before and when testing because thunderbird sets the
"smtp mail from" to the same address as a custom "message from" header. but
other mail clients don't have to do that.

should fix issue #22
2023-03-30 10:38:36 +02:00
Mechiel Lukkien
0989e59567
remove pgp and s/mime from possible future feature list
for issue #23
2023-03-29 21:24:59 +02:00
Mechiel Lukkien
df6956bed8
the mbox export also contains all message flags, so fix the text along the export links 2023-03-29 21:21:43 +02:00