Commit Graph
3236 Commits
Author SHA1 Message Date
Wez Furlong 91c0c2ac57 mailparsing: fallback to Content-Type::name for attachment name
Adjusts how we resolve the attachment name when processing mime
attachment parameters:

* First check Content-Disposition::filename
* Then check Content-Type::name

De-couple parsing out the `Content-Id` header from having
`Content-Disposition`.

In the lua bindings; remove the synthesized filename fallback;
we now just leave it nil to match the rust logic.
2025-09-10 10:42:48 +01:00
Wez Furlong 1170bb147f mailparsing: formalize attachment filename encoding in parser structs
This allows us to round-trip the non-conforming encoding scheme
that is in common use, and to emit it from our own mime builder
when attaching parts with non-ascii filenames.
2025-09-10 10:20:54 +01:00
Wez Furlong 93e87fc12e mailparsing: make Rfc2045Info::new infallible
If it fails, then the overall message parse attempt fails out,
but we want to allow operating on the borked message at some
basic level.

This commit adjusts the logic to assume reasonable fallback
values in case the various `Content-XXX` header parsing fails,
and to defer eg: detection of an unsupported charset until
the point where the content conversion is attempted.

The invalid headers are recorded as a new INVALID_MIME_HEADERS
conformance flag which causes check_fix_conformance to decide
that the message needs to be rebuilt.  The rebuild process
will come up with its own Content-XXX headers for the rebuilt
message through its existing logic.
2025-09-10 09:17:51 +01:00
Wez Furlong 466a59df44 mailparsing: accept commonly misphrased mime parameter header encoding
What a mess!

RFC 2047 defines an encoded-word as a way to indicate that some
text has 8-bit content and a specific charset, allowing for inline
transfer encoding to be applied to it.

It expressly says:

An 'encoded-word' MUST NOT appear within a 'quoted-string'.
An 'encoded-word' MUST NOT be used in parameter of a MIME
Content-Type or Content-Disposition field, or in any structured
field body except within a 'comment' or 'phrase'.

Today we encountered this header:

`Content-Disposition: attachment; filename="=?UTF-8?B?5pel5pys6Kqe44Gu5re75LuY?="`

which violates both of those restrictions.

RFC 2231 is a different RFC that specifies how to encode these sorts of
headers correctly.

Hunting around a bit on the internet, it appears that someone started to
use the bogus form, perhaps as a transitional workaround, or perhaps by
mistake, and it has become something of a de-facto accepted standard to
the point that gmail and fastmail both will generate this header
construction when attaching messages.

So we need to be able to parse these out.

This commit introduces a special case for this as the last step in the
MimeParameters::get method that will try to decode the retrieved value
as an encoded-word, and if successful, return that decoded value.
2025-09-10 02:55:27 +01:00
kay ozaki 934a8eebab adding crc32
closes: https://github.com/KumoCorp/kumomta/pull/404
2025-09-09 14:35:48 +01:00
Wez Furlong 7fffccf410 Add support for generating NDRs
This commit adds some plumbing to facilitate generation of RFC 3464
non-delivery reports and some corresponding glue to enable calling
it from lua.

Examples in the docs that are also added.
2025-09-09 14:12:52 +01:00
Wez Furlong 53a6bc3b7e log_hooks: add helper for creating a disposition hook 2025-09-09 10:39:52 +01:00
Wez Furlong dc475d4238 logging: introduce a log_disposition event hook
The higher level goal is to facilitate generation of RFC 3464
messages in response to delivery failures.

The first step is to introduce this synchronous (wrt. message processing
flow) event hook that will allow the message content to be optionally
captured by the hook implementation.  These need to be synchronous in
this way, otherwise a terminal dispoisition (eg: permanent failure) may
decide to remove the message from the spool concurrent with the log
processing.  That concurrency concern doesn't exist for the existing
logger implementations because they make a point of capturing all
information from the message prior to enqueuing the data to the logger.

Later commits will provide some convenience functions for bounce message
generation based upon that state.
2025-09-09 10:39:51 +01:00
Wez Furlong a478a0675d integration-tests: add helper for constructing tests
Makes it a bit more scalable to configure DaemonWithMaildir in tests
2025-09-09 10:39:51 +01:00
Wez Furlong c7cbd99a9f add kumo.inject_message 2025-09-09 10:38:36 +01:00
Wez Furlong 1bf9d138ce extended lua mime parsing API
refs: https://github.com/KumoCorp/kumomta/issues/117

Could also make it possible to do eg:
https://github.com/KumoCorp/kumomta/issues/142
without any explicit direct support in the product.
2025-09-09 09:15:58 +01:00
Wez Furlong a55db836e1 mkdocs_macros.py: be smarter about install links
At some point in the past month or two, mkdocs started to fail for
me when docs use `{{since('dev')}}` to reference the install page.

The failure is because we didn't know the correct number of ../
to emit when computing the relative path to the root, because
mkdocs doesn't support absolute paths to other markdown files.

This commit does some grubbing around to try to figure out whether we
are `foo.md` vs. `foo/index.md` because that is the heart of the
problem: both pages would be reported as having `page.url = 'foo/'` but
the markdown links need to consider the file on the filesystem rather
than the effective URL path.
2025-09-09 09:13:49 +01:00
Wez Furlong 4ea097878a fixup now-unused import 2025-09-02 09:46:33 +01:00
dependabot[bot] 8997779525 build(deps): bump actions/checkout from 4 to 5
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-09-01 23:35:28 -07:00
Wez Furlong 89c24e58cd cargo update
closes: https://github.com/KumoCorp/kumomta/pull/415
2025-09-02 07:33:23 +01:00
Sophia Turner 3088eda7e8 fix up match on bools 2025-09-01 23:33:13 -07:00
Sophia Turner 1917b7254a remove unnecessary derives 2025-09-01 23:31:35 -07:00
Mike Hillyer 9c16e45a92 Working on clarifying the scopes used in Kumo's shaping.lua. 2025-08-28 11:46:12 -04:00
Daniel Schaaff 3a42354289 fix prettier removing indentation on note section
Signed-off-by: Daniel Schaaff <daniel@danielschaaff.com>
2025-08-28 10:21:44 -04:00
Daniel Schaaff 1bcb2c31ac fix minor typo in logging doc 2025-08-28 10:21:44 -04:00
Sophia Turner 9c0b7511b1 fix up some lifetime hiding 2025-08-25 23:55:24 -07:00
smsvip 05d4a23b60 Update set_smtpsrv_threads.md
Repair set_smtpsrv_threads documents
2025-08-25 22:20:23 -04:00
dependabot[bot] 9f07628ecc build(deps): bump actions/download-artifact from 4 to 5
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-13 07:54:17 +01:00
Wez Furlong 636bdd7304 cargo update 2025-08-13 07:15:59 +01:00
Wez Furlong f85094282f migrate run-lua-test to rust
At least one of our supported platforms doesn't have a new enough
python to run the python version, let's just use rust for this.
2025-08-13 07:09:53 +01:00
Wez Furlong c28560b4f5 run-lua-test: fixup when run as root (eg: in CI)
Need to pass `--user` in that case
2025-08-11 14:21:02 +01:00
Wez Furlong 9f316ed689 ci: improve run-lua-test
This commit:

* Adds auto-discovery of both module style and crate style tests
* Runs each test via its own instance of `kumod`, so that one test
  cannot pollute the state of another
* Runs all lua tests concurrently
2025-08-11 13:24:41 +01:00
Tom Mairs a1a5f71852 Update note about minimum supported instance 2025-08-08 14:47:18 +00:00
Wez Furlong 6a05a65f73 mpsc: provide shutdown event and clarify single-consumer parts
It was possible to deadlock your policy by triggering queue
length/emptiness checks conurrently with the queue consumer thread.

Let's make it more explicitly clear which methods cannot be used that
way by making their mutex acquisition non-blocking and raise an error.

In addition, let's improve the close method so that it doesn't require
exclusive access to the consumer side of the queue.

Provide a shutdown_logging event that can be used to explicitly close
queues on shutdown, if that is appropriate for your use case.
2025-07-29 15:22:51 +01:00
Tom Mairs 634a00ec6f Add new tested cloud environments 2025-07-27 22:50:10 +00:00
Wez Furlong 4f43ab92a0 mod-filesystem: add missing append mode 2025-07-27 06:55:14 +01:00
Wez Furlong 91884d3892 docs: format 2025-07-26 13:30:00 +01:00
Wez Furlong 33b109c792 docs: changelog for #399 2025-07-25 06:05:53 +01:00
Wez Furlong bc7c95b42a docs: changelog for #394 2025-07-25 06:02:57 +01:00
Pankaj RathiandWez Furlong eae61a90fe Add support for custom key names in HashiCorp Vault secrets (#399)
* Add support for custom key names in HashiCorp Vault secrets

Co-authored-by: Wez Furlong <wez@wezfurlong.org>
2025-07-25 06:02:21 +01:00
Daniel Schaaff 25a292a82e add support for compressing http body (#394)
* implement support for compression in common http server code

Adds a decompression layer to enable receipt and automatic decompression of compressed request bodies.

Signed-off-by: Daniel Schaaff <daniel@danielschaaff.com>
2025-07-25 05:56:12 +01:00
Wez Furlong 9e62a275c5 add tls_required_client_ca esmtp listener parameter
This enables configuring mTLS support in the listener.

Adjust TLS client tests to use this on the sink side and verify
that mTLS works for both inbound and outbound SMTP.

refs: #100
refs: #391
2025-07-24 15:40:49 +01:00
Wez Furlong a2fb749088 tls_client_certificate: fix performance, assert tls info
Fix the performance of the success test cases (they would wait 50s for a
TransientFailure that would never occur).

Add assertion for new server tls info being set and recorded in the
Reception log records on the sink side.

refs: #100
refs: #391
2025-07-24 13:14:25 +01:00
Wez Furlong c8027effb6 smtp_server: collect incoming tls information for logs/meta
This commit extracts the TLS version, cipher and subject name from
the TLS state and captures it:

* In the trace headers
* In the connection metadata
* In the Reception log record

In order to capture the info in trace headers, this commit will
now change the reception protocol to ESMTPS (for SSL) or ESMTPSA (for
authenticated SSL), and emit the version and cipher information as
a comment like: `with ESMTPS (TLSv1_3:TLS13_AES_256_GCM_SHA384)`.

closes: #100
2025-07-24 13:01:13 +01:00
kayozaki 76add2ced5 Adding support for presenting Client cert as part of make_egress_path (#391) 2025-07-24 13:00:27 +01:00
Wez Furlong 7e6ca34e2d new: kumo.fs lua module
The read_dir and glob functions have been logically moved into that new
namespace, leaving deprecated versions of them in the `kumo` module.

A new `kumo.fs.open` function that works similarly to `io.open` is
provided.  This function cooperates with the kumo async io scheduler
and won't block it if the filesystem is under pressure.

It returns file handles that are simlar to the builtin lua file handle
objects, but do not support formatting or parsing of writes or reads
respectively: the calling code is responsible for that.  The rationale
for this difference is that is that lua's semantics for those functions
are frankly a bit weird and are hard to replicate precisely.
2025-07-23 16:51:06 +01:00
Wez Furlong 7d617bb270 add kumo.mpsc.define
This function allows defining a non-durable, non-persistent, in-memory
queue that is intended to be used as glue when building up more advanced
processing flows within kumomta.

The intent is that the queue is processed from within a task spawned via
`spawn_task`.
2025-07-23 12:44:10 +01:00
Tom Mairs 88b182d3c3 removed duplication 2025-07-22 23:08:46 +00:00
Tom Mairs 7064344b04 Update list of command line tools 2025-07-22 22:49:12 +00:00
Wez Furlong 7903dff857 docs: update json file versions
these were lagging behind due to a local configuration issue
on my build system in an earlier commit.
2025-07-22 09:08:40 +01:00
Wez Furlong 5a3c942675 docs: update for #390 2025-07-22 09:08:18 +01:00
Wez Furlong ca4593b284 cargo update 2025-07-22 08:45:39 +01:00
kayozakiandWez Furlong a7315633de add kumo.dns.lookup_ptr (#390)
* add lookup_ptr

Co-authored-by: Wez Furlong <wez@wezfurlong.org>
2025-07-22 08:45:27 +01:00
Wez Furlong fa5d6a6e7a allow specify port number in queue and routing_domain meta
The motivating use case here is to allow using a rebind command to
specify `smarthost:port`.  You can achieve that via an invocation
like:

```
kcli rebind --everything --set queue=smarthost:port
```

or:

```
kcli rebind --everything --set routing_domain=smarthost:port
```

refs: https://github.com/KumoCorp/kumomta/issues/352
2025-07-21 15:38:28 +01:00
Wez Furlong 58729832c9 message: unit tests for parsing routing_domain with port
No functional changes, just adds some illustrative unit tests
that show that the routing domain portion of the queue name
string can accept a port number.

The system doesn't understand what to do about that at this
time.

refs: https://github.com/KumoCorp/kumomta/issues/352
2025-07-21 12:34:59 +01:00