Commit Graph

487 Commits

Author SHA1 Message Date
Wez Furlong 1d8ce2bb74 http inject: add integration test for request_body_limit
This commit doesn't change any behavior, it just adds an explicit
test for exceeding request_body_limit, and expands on the docs
for request_body_limit to clarify the response when the limit
is exceeded.
2026-01-15 13:52:10 +00:00
Wez Furlong 5b20731ea4 docs: restore proper version for template_dialect
This was accidentally lost in 75debad675
2026-01-07 07:48:20 +00:00
Wez Furlong 885c4914ca docs: update openapi spec for amp_html 2026-01-07 07:46:27 +00:00
Mike Hillyer 75debad675 Updating headings in Inject API doc so that sidebar menu populates correctly. 2026-01-06 12:23:49 -05:00
Wez Furlong 0a112417c0 Add support for AMP in the message builder and injection APIs 2025-12-19 06:37:27 +00:00
Aditya Ganti af59493e00 Add aws_sign_v4 helper on kumo.http.Request (#458)
* Add aws_sign_v4 helper to kumo.http.Request and cross-link docs

Co-authored-by: Aditya Ganti <adityaganti@mac.mynetworksettings.com>
2025-12-18 07:14:36 -07:00
Wez Furlong 07ab3d44a3 inject+xfer: cut over to AuthInfo from AuthKind
Replace the older type with the newer one.

Serialize a copy of auth_info when handling deferred generation,
so that we have a lossless representation of that state when
we eventually process the request.  That doesn't change really
anything today, but will enable more granular ACL checks in
the future.

Pass the auth_info through to the http_message_generated and
xfer_message_received events to enable more granular access
control policies to be scripted.
2025-12-18 10:19:09 +00:00
Wez Furlong 5926112956 acct: add kumo.aaa.configure_acct_log
This function sets up the accounting log which records authentication
and authorization events to a local log file.

Add some test assertions that we're not seeing any failed authn/authz
in a number of integration tests.

Add explicit check for failed a request to kcli's streaming metrics
parser, which previously would ignore the request status.
2025-12-18 08:22:31 +00:00
Wez Furlong 3e85297fca authn: allow returning AuthInfo from smtp/http auth event callbacks
This commit allows the policy to return a richer representation of
the authentication information, which can include multiple identities
and group membership information.
2025-12-18 06:30:06 +00:00
Wez Furlong 4055c50522 authz: introduce an ACL facility
This commit is a step towards some general improvements around
our handling of authentication and authorization.

This commit is focused primarily on authorization, but there are
some adjustments to how we track authentication as part of enabling
that.

We now have a separate AuthInfo type that holds the overall
authentication information/context associated with an inbound
SMTP or HTTP session.

It is populated with the peer_address as a fact rather than a statement
of trust.

If authentication via the appropriate lua auth callback is successful,
then the AuthInfo has additional identities added.

There are some types and events for loading access control lists and
matching their rules against an AuthInfo.

There is now a system default ACL that is equivalent to the prior
hard-coded access policy that was encoded into each HTTP endpoint.

This change makes it possible to replace the ACL with a
user-defined ACL.

Later will be some work on authentication to allow more options
for HTTP auth.
2025-12-18 06:30:06 +00:00
Wez Furlong b551d6b4c7 docs: update for release 2025.12.02-67ee9e96 2025-12-02 11:11:05 +00:00
Wez Furlong 67ee9e96ea docs: mail_auth: dmarc is implemented and available 2025-12-02 10:54:29 +00:00
Wez Furlong c379a931a1 docs: fix typo 2025-11-27 17:18:11 +00:00
Wez Furlong 38a15fe891 docs: format aws_sign_v4
refs: https://github.com/KumoCorp/kumomta/pull/457
2025-11-25 13:16:20 +00:00
Aditya Ganti b96dd0843f Add AWS SigV4 signature module (#457)
* Add AWS SigV4 signature module

 - Implements complete AWS Signature Version 4 algorithm
 - Supports all AWS services (S3, SNS, SQS, Kinesis Firehose, etc.)
 - Includes SHA256 hashing and HMAC-SHA256 signing
 - Secure key management via KeySource (files, Vault, inline)
 - Session token support for temporary credentials
 - Comprehensive documentation and examples
 - 5 unit tests and 5 integration tests (all passing)

 Exposes kumo.aws.sign_v4() function to Lua for signing AWS API
 requests. This enables KumoMTA to integrate with AWS services for
 streaming logs to Kinesis Firehose, storing data in S3, sending
 notifications via SNS, and more.

 Tested with:
 - S3 GET/PUT requests
 - SNS POST requests
 - SQS with query parameters
 - Kinesis Firehose PutRecord

updating README.md file

Co-authored-by: Aditya Ganti <adityaganti@mac.mynetworksettings.com>
2025-11-25 06:14:48 -07:00
Wez Furlong 245221ae29 docs: clarify Time and TimeDelta
It wasn't clear that these pages were describing a class rather than a
literal object.

Add some more usage examples.
2025-11-20 15:26:42 +00:00
Wez Furlong 027e3e9f75 docs: wrap examples in normalize_smtp_response.md 2025-11-20 14:54:26 +00:00
Wez Furlong 7b240db3e1 docs: fix copypasta in smtp_server_rewrite_response page
It said smtp_CLIENT instead of server
2025-11-20 14:53:03 +00:00
Wez Furlong 2023aba6af docs: mention template dialect in injection and eval_template APIs 2025-11-20 14:50:15 +00:00
Wez Furlong 3781ff7d95 docs: format 2025-11-19 07:57:37 +00:00
Wez Furlong 6f53931fde add kumo.invoke_get_egress_(pool|source)
These functions are similar to the existing
invoke_get_egress_path_config and invoke_get_queue_config functions;
they return the configuration information that is defined by your
overall policy in the same way that the system does.

The intent is for more advanced policies that need that info to
decide how to configure other parts of the policy.

Docs are included, and I fleshed out the missing docs for the two
pre-existing functions.
2025-11-14 07:04:58 +00:00
Wez Furlong 4c89acae96 docs and changelog for require_proxy_protocol #440 2025-11-13 15:27:39 +00:00
Wez Furlong f2f792e74f kumo.digest: add various HMAC_SHAXXX functions 2025-11-13 12:06:32 +00:00
Wez Furlong fdd2276dfb mod-digest: switch from ring::digest to aws-lc-rs::digest
Switch away from ring to aws-lc-rs which API compatible and has support
for more digest algorithms.

Add support for all of the current algorithms.
2025-11-13 11:10:13 +00:00
Wez Furlong 26a0c86c49 Expose version number to lua via kumo.version
I'm surprised that we didn't already do this!
It allows phrasing the policy to accommodate different versions
of kumo.
2025-11-13 06:30:35 +00:00
Wez Furlong 4917ee6245 prohibited_hosts: add v4 and v6 any address
Saw an MX record that expands to 0.0.0.0 in the wild.

As well as being nonsense, that causes a mail loop, so we should add it
to prohibited_hosts.

I noticed that we also did not document its default value, so the
doc update here shows the before and after for this.
2025-11-10 15:09:11 +00:00
Wez Furlong d4028f9931 Add smtp response text normalizer 2025-11-09 08:09:51 +00:00
Wez Furlong ad8a858136 templates: add Handlebars dialect
This is fairly barebones: there are very few helpers at this time.

refs: https://github.com/KumoCorp/kumomta/issues/446
2025-11-09 07:53:20 +00:00
Wez Furlong e106c3d496 template: add Static engine
This engine does no templating; the source text is output exactly
as it was entered into the template engine.

Expose template_dialect to the http injection API and add a test
to show that selecting the Static dialect doesn't perform any
template expansion.

refs: https://github.com/KumoCorp/kumomta/issues/446
2025-11-09 07:53:19 +00:00
Wez Furlong 7ac9a5eac0 smtp_dispatcher: handle pathologic all-452 case
Continuing in the same vein as 94628f06ab,
ensure that we have a reasonable outcome when a batch of size > 1
encounters 100% ambiguous 452 responses.

Without special consideration we'd end up in an infinite retry loop for
these, as we'd think that we'd hit the recpient limit on the connection
every time.

This commit introduces a small amount of state into the dispatcher so
that we can remember the set of (spoolid, recipient) from the prior
transaction on the session.

When deciding whether something is eligible for immediate retry
we will gate that choice on the current (spoolid, recipient) being
absent from the prior set of ids.  In this way, we bound the immediate
retry for a recipient to one per connection.

To make things a bit more robust when trying to decide whether a 452
means "too many recipients" or not, if we're not sure, we now call out
to the bounce classifier which can be configured to emit a
`TooManyRecipients` classification.  If the classifier produces either
that or some non-Uncategorized response, then we have a confident
assessment.  Otherwise, we're unsure and will factor that into the
retry strategy.
2025-11-07 08:13:36 +00:00
Wez Furlong 4c6d7ca8ea add policy-extras.mail_auth module
This aggregates the various authentication-results producing auth checks
into a more convenient function.

Part of this change improves some plumbing in the dkim checking (we no
longer raise an error for a missing From, but instead indicate a failed
dkim result), and we now support passing down a resolver name to the
various checking functions, to facilitate testing and other more
advanced use cases.

refs: https://github.com/KumoCorp/kumomta/issues/16
refs: https://github.com/KumoCorp/kumomta/issues/84
2025-11-02 11:56:57 +00:00
Wez Furlong 49cdee1ec5 lruttl: expose pre-defined cache info to the docs
This commit adds some plumbing to allow us to collect metadata
about the caches and spit it out into a json file that we can
then use in the docs to show the predefined caches, capacities
and brief comments about their purpose.

We put that info on the set_lruttl_cache_capacity doc page.
2025-11-01 07:40:40 +00:00
Wez Furlong 5ad7df0203 arc: expose arc_seal and arc_verify methods to lua
refs: https://github.com/KumoCorp/kumomta/issues/16
2025-10-31 12:16:32 +00:00
Wez Furlong 6adb43221f Expose text wrapping function as kumo.string.wrap
Extracts the wrap function to its own little crate and expose that to
lua.
2025-10-29 12:06:06 +00:00
Wez Furlong 67bf14ca20 improve header wrapping functions
Augment the docs to clarify that msg:append_header and
msg:prepend_header do no modification of the value by default.

Adjust the wrapping used by Header:new_unstructured so that it
hard wraps before the SMTP line length limit.

Add optional encode parameter to msg:append_header and
msg:prepend_header so that those methods can opt-in to the
Header:new_unstructured formatting.

Add HeaderMap:append method to mirror the existing HeaderMap:prepend
method.

Add unit tests that demonstrate the effect of wrapping/encoding
for both the "dumb" msg:append_header and msg:prepend_header functions,
and the "smarter" HeaderMap:prepend and HeaderMap:append methods that
always encode their parameters.

Update the docs for the headermap flavor of these methods to indicate
that they will always encode the value.
2025-10-29 11:35:42 +00:00
Wez Furlong 1d70c2ffbb new smtp_server_rewrite_response event
This allows you to customize or otherwise adjust the responses
made by the smtp server.
2025-10-29 08:54:10 +00:00
Wez Furlong 47aac10ea6 data-loader: allow callback/event based loading of secrets
This allows a (more or less) arbitrary lua function to be used to load
data.

The primary advantage of this is that the size of the resulting
KeySource struct is smaller than it would be to hold the actual data
inline.  It also enables the surrounding code to be slightly better
factored.
2025-10-24 13:41:27 +01:00
Wez Furlong 6f31d5514c new Time and TimeDelta objects for lua
Motivated by https://github.com/KumoCorp/kumomta/pull/403,
this commit introduces reasonably full featured Time and TimeDelta
types built atop the chrono crate.

closes: https://github.com/KumoCorp/kumomta/pull/403
2025-10-22 17:26:35 +01:00
Dario Maiocchi 847cc21e9b implement aes-cbc block with examples
Add CBC and ecb Block mode aes encryption/decryption.

To facilitate testing this better, and just to be nicer overall, adjust
data-loader's KeySource::key_data variant to support loading raw binary
bytes.

Co-authored-by: Wez Furlong <wez@wezfurlong.org>

Closes: https://github.com/KumoCorp/kumomta/pull/395
2025-10-22 11:55:16 +01:00
Wez Furlong 6fc0d782ff spf: populate smtp.mailfrom in Auth-Results, add check_msg func
Add a convenience function that is intended to be used around the
time that you might be building up the overall set of
Authentication-Results.

Populate missing smtp.mailfrom in SPF authentication result.
2025-10-21 21:25:21 +01:00
Wez Furlong aac842439f smtp_server: increase line_length_hard_limit default to 1000
We were including the CRLF in the measurement that we were making,
while the default value was the value from the spec excluding the CRLF.
Let's increase the default value to 1000 to make things match up.
2025-10-13 09:53:03 +01:00
Wez Furlong 6197367312 docs: add splitting step to event sequence diagram 2025-10-11 07:13:06 +01:00
Wez Furlong 7311510ff6 docs: recip needs to be an array in this example 2025-10-11 07:09:11 +01:00
Wez Furlong a81493a17e docs: remove extraneous quotes 2025-10-11 07:07:54 +01:00
Wez Furlong b73d81b0fc dns: utilities and plumbing for querying DNSBLs
This commit does some plumbing work to allow defining alternative
resolvers with different names that can be used to query different
upstream DNS servers.

This is most useful when implement DNSBLs where you might have a custom
DNS server configured with one or more RBL zones that is reserved purely
for RBL lookups.

The plumbing introduces a more regular syntax for defining one of the
various implementations of the Resolver trait, as well as a new
Aggregate resolver impl that can query across multiple Resolvers until a
query is satisfied.

This allows some interesting and powerful configurations, such as
loading a static zone file into memory to query it directly, and/or
blending that together with querying either the system or some other
upstream DNS server as a fallback.

The various lookup functions (except for MX!) have been updated to
accept an optional alternate resolver name, so that they work together
with the above.

A new rbl_lookup function is also provided as a convenience for querying
the most common form of RBLS.

ptr_host and reverse_ip are two string utility functions that are likely
not going to be widely used, but are very convenient to have when you
do have a usecase that requires it!

closes: https://github.com/KumoCorp/kumomta/issues/269
2025-10-10 18:45:52 +01:00
Wez Furlong 5b914a597a deprecating the lapin-based amqp client
This never worked as well as the other amqp option that we support,
and upgrading it to the current version is a bit of a chore.

I'd rather just drop this dep and keep things more trim.

Since none of our sponsors are using the lapin implementation, let's
mark it as deprecated and we can take it out after we cut the next
stable release.
2025-10-08 11:17:55 +01:00
Wez Furlong 8fc11713d8 deps: update axum and utoipa ecosystem crates
A "casualty" of this is that the client-ip crate, which we were using
for its InsecureClientIp type for informational purposes, has retired
the InsecureClientIp type because it wasn't trustworthy overall
(https://github.com/imbolc/axum-client-ip/issues/32).

What we do for the time being is configure that crate to use the direct
peer IP.  There isn't a way to automagically select the "best"
information available without building in some kind of middleware, and
we probably should make that configurable in order to be fully
trustworthy.

So for now, we're punting on that until someone shows up with some
requirements and sponsorship and we'll make it happen then.
2025-10-08 10:24:57 +01:00
Wez Furlong 5c98511c06 add new kumo.file_type module
This is useful for example when processing attachments as part of a
content scanning policy.
2025-10-07 12:12:46 +01:00
Wez Furlong 7f4a929ca2 message transfer (xfer) support
This commit implements a kumomta-specific message transfer
protocol that is intended to be used to migrate messages
from one kumomta node to another.

The transfer is carried out using an HTTP POST request
to the destination node's http listener.

The request includes the full message metadata and body,
in a compressed form.

An xfer request can be made via `kcli xfer` (and thus also via an HTTP API
endpoint).  It works similarly to a rebind operation; you specify the
criteria to be used to match scheduled queues, along with the target
node for the xfer, and kumomta will find matching queues, drain out the
messages, make an adjustment to the metadata to capture current
scheduling information, and then place the messages into an xfer queue.

The xfer queue has hard-coded scheduling queue configuration of its own,
with the base retry interval set to 10 seconds, which should be suitably
aggressive for the intended use case.

You may apply shaping to affect the number of concurrent requests in a
similar way to how TSA shaping is configured.

On the receiving side, the incoming xfer sanity check to prohibit
trying to xfer to itself.

The spool id of the Message is not suitable to be reused verbatim on
another node (spool ids include the local mac address and creation
timestamp information, as well as a random component), so the receiving
side will derive an id that should be suitable for use on that node.
The originating node id and spool id will be preserved in metadata to
aid in tracing.

It is possible for an xfer request to target an existing xfer queue, so
that you can correct/update the target in various circumstances. In that
situation the messages will be "simply" moved from the source queue to
the destination queue.

It is possible to cancel an xfer request via `kcli xfer-cancel` (and
thus also via an HTTP API endpoint).  You specify the target queue,
which must be an xfer queue, and it will have its messages drained and
the metadata changes that were applied when the xfer was initiated will
be reversed, allowing the messages to then be reinserted into their
originating queue.

refs: https://github.com/KumoCorp/kumomta/issues/311
2025-10-07 10:58:07 +01:00
Wez Furlong de6e3bd0de allow admin bounce and suspend to specify exact queue name 2025-10-07 08:43:16 +01:00