From 82ffdea433d472805fcd0b247dc0add94c80a2ff Mon Sep 17 00:00:00 2001 From: Julie Zhao Date: Mon, 25 Nov 2024 16:04:00 -0500 Subject: [PATCH 01/13] OpenARC module and APIs --- .../4/lua/ref-msys-validate-openarc-sign.md | 110 ++++++++++++++++++ .../4/lua/ref-msys-validate-openarc-verify.md | 62 ++++++++++ content/momentum/4/modules/index.md | 1 + content/momentum/4/modules/openarc.md | 44 +++++++ 4 files changed, 217 insertions(+) create mode 100644 content/momentum/4/lua/ref-msys-validate-openarc-sign.md create mode 100644 content/momentum/4/lua/ref-msys-validate-openarc-verify.md create mode 100644 content/momentum/4/modules/openarc.md diff --git a/content/momentum/4/lua/ref-msys-validate-openarc-sign.md b/content/momentum/4/lua/ref-msys-validate-openarc-sign.md new file mode 100644 index 000000000..22fbbd379 --- /dev/null +++ b/content/momentum/4/lua/ref-msys-validate-openarc-sign.md @@ -0,0 +1,110 @@ +--- +lastUpdated: "11/26/2024" +title: "msys.validate.openarc.sign" +description: "msys validate openarc sign seal add ARC set headers" +--- + + +## Name + +msys.validate.openarc.sign — builds and adds the ARC set headers into an email. + +msys.validate.openarc.seal - synonym of `msys.validation.openarc.sign`. + +## Synopsis + +`msys.validate.openarc.verify(msg, options, ar)` + +``` +msg: userdata, ec_message type +options: table +ar: string, optional. It's the message's authentication assessment to be enshrined into the AAR +(ARC-Authentication-Results) header. + +``` + +## Description + +This function does ARC validation first, then combine the validation result with authentication +assessments from other methods (e.g. SPF, DKIM, etc) defined by the `ar` and put it into the AAR +header; then sign and seal the message by adding the AMS (ARC-Message-Signature) and AS +(ARC-Seal) headers, using the signing mechanism defined in the `options` table. + +This function requires the [`openarc`](/momentum/4/modules/openarc) module. + +Enable this function with the statement `require('msys.validate.openarc')`. + +This function takes the following parameters: + +* `msg` - mail message to sign + +* `options` - table defines the options for signature generation/signing: + + * `signing_domain` – signing domain + + * `selector` – signing selector + + * `authservid` – authentication service identifier, as + [authserv-id](https://datatracker.ietf.org/doc/html/rfc8601#section-2.5) defined in RFC. + + * `header_canon` – header canonicalization setting + + * `body_canon` – body canonicalization setting + + * `digest` – signing algorithm digest setting + + * `keyfile` – signing key file + + * `keybuf` – signing key + + Must contain the PEM encoded private key to use for signing the + message. This must be a contiguous string, with no line breaks and no white spaces, without the + `BEGIN` and `END` tags that are found in the key file itself. The format is similar to the + format used for OpenDKIM signing. + + If not defined, will be built from the `keyfile`. + + * `headerlist` – ";" separated list of headers to sign + + * `oversign_headerlist` – ";" seperated list of headers for over signing + +* `ar` - authentication assessment to be enshrined in the AAR (ARC-Authentication-Results) header. + + If not provided, Momentum will take the value from the existing `Authentication-Results` header. + Momentum appends this value with the ARC verification result (e.g. `arc=pass`) and use it to + build the AAR header. + + +### Note + +Since ARC sealing should happen after all potential modification of a message is done, this function +shall be invoked in the `post_final_validation` stage after all the other validation phases. + + + +### Example + + +``` +require("msys.core"); +require("msys.extended.message"); +local openarc = require("msys.validate.openarc"); +local mod = {}; + +function mod:core_post_final_validation(msg, accept, vctx) + local sealer = {} + sealer.signing_domain = "sparkpost.com" + sealer.selector = "dkim-s1024" + sealer.keyfile = "path-to-keyfile" + sealer.headerlist = "From:Subject:Date:To:MIME-Version:Content-Type" + sealer.oversign_headerlist = "From:To:Subject" + + openarc.sign(msg, sealer) +end + +msys.registerModule("openarc_sign", mod); +``` + +## See Also + +[msys.validate.opendarc.verify](/momentum/4/lua/ref-msys-validate-openarc-verify) diff --git a/content/momentum/4/lua/ref-msys-validate-openarc-verify.md b/content/momentum/4/lua/ref-msys-validate-openarc-verify.md new file mode 100644 index 000000000..3b6ed25a1 --- /dev/null +++ b/content/momentum/4/lua/ref-msys-validate-openarc-verify.md @@ -0,0 +1,62 @@ +--- +lastUpdated: "11/26/2024" +title: "msys.validate.openarc.verify" +description: "msys validate openarc verify Verify ARC sets headers" +--- + + +## Name + +msys.validate.openarc.verify — Verifies ARC set headers in an email, stores the verification results +(`none/pass/fail`) into the email's context variable. + +## Synopsis + +`msys.validate.openarc.verify(msg)` + +`msg: userdata, ec_message type` +## Description + +This function validates the ARC set headers contained in the input message. The validation result +will be stored as string value (`none` or `pass` or `fail`) in the `ec_message`'s context variable +of `arc_cv`. A caller can take actions (e.g. disposition of the message) based on the validation +result. + +This function requires the [`openarc`](/momentum/4/modules/openarc) module. + +Enable this function with the statement `require('msys.validate.openarc')`. + +### Note + +If the `ec_message` context variable `arc_cv` is not set after this function call, errors happened +and logged into paniclog. + +This function invokes dns lookup for signature validation. It's recommended to invoke it from a hook +which would not block Momentum's main tasks, e.g. from the `validate_data_spool` hook. + + +### Example + + +``` +require("msys.core"); +require("msys.extended.message"); +local openarc = require("msys.validate.openarc"); +local mod = {}; + +function mod:mod:validate_data_spool(msg, ac, vctx) + openarc.verify(msg) + local cv = msg:context_get(msys.core.ECMESS_CTX_MESS, "arc_cv") + if cv then + print("ARC validation result: ", cv) + else + print("Failed to do ARC validation. Check paniclog for reasons.") + end +end + +msys.registerModule("openarc_verify", mod); +``` + +## See Also + +[msys.validate.opendarc.sign](/momentum/4/lua/ref-msys-validate-openarc-sign) diff --git a/content/momentum/4/modules/index.md b/content/momentum/4/modules/index.md index 164907132..e21809faa 100644 --- a/content/momentum/4/modules/index.md +++ b/content/momentum/4/modules/index.md @@ -60,6 +60,7 @@ description: "Table of Contents 71 1 Introduction 71 2 ac auth Authentication Ha | [msgc](/momentum/4/modules/msgc) | Message Systems Group Communication | | [msg_gen](/momentum/4/modules/msg-gen) | Message Generation | | [mxip](/momentum/4/modules/mxip) | IP Addresses In MX Records | +| [openarc](/momentum/4/modules/openarc) | Open Source ARC | | [opendkim](/momentum/4/modules/opendkim) | Open Source DKIM | | [outbound_audit](/momentum/4/modules/outbound-audit) | Outbound traffic analytics | | [outbound_smtp_auth(modules.outbound_smtp_auth.php) | diff --git a/content/momentum/4/modules/openarc.md b/content/momentum/4/modules/openarc.md new file mode 100644 index 000000000..6f3f17813 --- /dev/null +++ b/content/momentum/4/modules/openarc.md @@ -0,0 +1,44 @@ +--- +lastUpdated: "11/26/2024" +title: "openarc – Open Source ARC" +description: "The openarc module wraps the open source libopenarc API into Momentum to provide Momentum APIs to do ARC validation verification signature signing and sealing..." + +ARC is an acronym for Authenticated Received Chain. It’s a technology protocol defined in +[RFC8617](https://datatracker.ietf.org/doc/html/rfc8617). It provides an authenticated "chain of +custody" for a message, allowing each entity that handles the message to see what entities handled +it before and what the message's authentication assessment was at each step in the handling flow. + +The openarc module add ARC capability to Momentum. It provides Lua APIs for +ARC validation on a received email, and ARC siging and sealing on an outgoing email. +When the module is enabled, ARC validation and signing/sealing can be achieved through calling these APIs from hook policies. + + +### Configuration + +You need to enable the openarc module in the ecelerity configuration file to use the feature: + +``` +openarc {} +``` + +### Lua APIs and examples + +[msys.validate.opendarc.verify](/momentum/4/lua/ref-msys-validate-openarc-verify) + +[msys.validate.opendarc.sign](/momentum/4/lua/ref-msys-validate-openarc-sign) + + +### Hook points to invoke the APIs + +The `msys.validate.opendarc.sign` does verification first. You should only invoke one of the APIs, + either `verify` or `sign` but not both. +It's recommended to invoke `msys.validate.opendarc.verify` in `validate_data_spool` hook. +`msys.validate.opendarc.sign` shall be invoked in the last validation phase, in +`post_final_validation` hook. + +The `post_final_validation` hook is added as the absolute last point before writing the message into +spool. No any message modification expected after this stage. To avoid undefined race between +multiple implementations of the same hook, you shall only have up to one implementation for this +hook. And it's the best place to call `msys.validate.opendarc.sign`. + +See API examples for hook usages. From 20f4aebeda51a1e7f022f2c15afb8b3d447fd656 Mon Sep 17 00:00:00 2001 From: Julie Zhao Date: Tue, 26 Nov 2024 08:31:51 -0500 Subject: [PATCH 02/13] typo --- content/momentum/4/modules/openarc.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/content/momentum/4/modules/openarc.md b/content/momentum/4/modules/openarc.md index 6f3f17813..e6e4cf99d 100644 --- a/content/momentum/4/modules/openarc.md +++ b/content/momentum/4/modules/openarc.md @@ -13,7 +13,8 @@ ARC validation on a received email, and ARC siging and sealing on an outgoing em When the module is enabled, ARC validation and signing/sealing can be achieved through calling these APIs from hook policies. -### Configuration + +### Configuration You need to enable the openarc module in the ecelerity configuration file to use the feature: @@ -41,4 +42,4 @@ spool. No any message modification expected after this stage. To avoid undefined multiple implementations of the same hook, you shall only have up to one implementation for this hook. And it's the best place to call `msys.validate.opendarc.sign`. -See API examples for hook usages. +See API examples for hook usages. From f954f8673458b0d112a2967ea6558ad9e8584e29 Mon Sep 17 00:00:00 2001 From: Julie Zhao Date: Tue, 26 Nov 2024 08:50:19 -0500 Subject: [PATCH 03/13] typo --- content/momentum/4/modules/openarc.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/momentum/4/modules/openarc.md b/content/momentum/4/modules/openarc.md index e6e4cf99d..2c25a1488 100644 --- a/content/momentum/4/modules/openarc.md +++ b/content/momentum/4/modules/openarc.md @@ -2,6 +2,7 @@ lastUpdated: "11/26/2024" title: "openarc – Open Source ARC" description: "The openarc module wraps the open source libopenarc API into Momentum to provide Momentum APIs to do ARC validation verification signature signing and sealing..." +--- ARC is an acronym for Authenticated Received Chain. It’s a technology protocol defined in [RFC8617](https://datatracker.ietf.org/doc/html/rfc8617). It provides an authenticated "chain of @@ -13,8 +14,7 @@ ARC validation on a received email, and ARC siging and sealing on an outgoing em When the module is enabled, ARC validation and signing/sealing can be achieved through calling these APIs from hook policies. - -### Configuration +### Configuration You need to enable the openarc module in the ecelerity configuration file to use the feature: From aa06676057ece464061064be891a2e078d9a42eb Mon Sep 17 00:00:00 2001 From: Julie Zhao Date: Tue, 26 Nov 2024 10:38:26 -0500 Subject: [PATCH 04/13] add ref to post_final_validation hook --- content/momentum/4/4-lua-summary-table.md | 2 ++ content/momentum/4/hooks/index.md | 5 +++-- content/momentum/4/lua/index.md | 2 ++ content/momentum/4/modules/openarc.md | 10 +++------- content/momentum/4/modules/summary-all-modules.md | 1 + 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/content/momentum/4/4-lua-summary-table.md b/content/momentum/4/4-lua-summary-table.md index c7cab4480..a427611f4 100644 --- a/content/momentum/4/4-lua-summary-table.md +++ b/content/momentum/4/4-lua-summary-table.md @@ -174,6 +174,8 @@ This section contains tables of Lua functions. Click the function name for detai | [msys.unlock](/momentum/4/lua/ref-msys-unlock) – Releases a lock obtained via msys.lock | mutexname | msys | 4.0 | any | | [msys.validate.dk.get_responsible_domain](/momentum/4/lua/ref-msys-validate-dk-get-responsible-domain) – This function requires module "dk_validate". "msg" is a mail message. "ctx" is the validation context. It returns the responsible domain for the current message | msg, ctx | msys.validate.dk | 4.0 | data, data_spool, data_spool_each_rcpt | | [msys.validate.dk.sign](/momentum/4/lua/ref-msys-validate-dk-sign) – Sign a message using a Domain Key | msg, ctx, options | msys.validate.dk | 4.0 | core_data_validation | +| [msys.validate.openarc.sign](/momentum/4/lua/ref-msys-validate-openarc-sign) – Sign a message using OpenARC | msg, options, [ar] | msys.validate.openarc | 5.0 | core_post_final_validation | +| [msys.validate.openarc.verify](/momentum/4/lua/ref-msys-validate-openarc-verify) – Verify ARC sets | m | msys.validate.openarc | 5.0 | data_spool, data_spool_each_rcpt | | [msys.validate.opendkim.get_num_sigs](/momentum/4/lua/ref-msys-validate-opendkim-get-num-sigs) – Return the number of DKIM signatures | dkim | msys.validate.opendkim | 4.0 | data, data_spool, data_spool_each_rcpt | | [msys.validate.opendkim.get_sig](/momentum/4/lua/ref-msys-validate-opendkim-get-sig) – Get a signature from a DKIM object | dkim, [num] | msys.validate.opendkim | 4.0 | data, data_spool, data_spool_each_rcpt | | [msys.validate.opendkim.get_sig_canons](/momentum/4/lua/ref-msys-validate-opendkim-get-sig-canons) – Fetch the canonicalizers used for a DKIM signature | dkim_sig | msys.validate.opendkim | 4.0 | data, data_spool, data_spool_each_rcpt | diff --git a/content/momentum/4/hooks/index.md b/content/momentum/4/hooks/index.md index cac445446..24c2ab346 100644 --- a/content/momentum/4/hooks/index.md +++ b/content/momentum/4/hooks/index.md @@ -1,6 +1,6 @@ --- -lastUpdated: "10/05/2021" -title: "Category File" +lastUpdated: "11/26/2024" +title: "Hook Points and C Functions Reference" type: "custom" name: "Hook Points and C Functions Reference" description: "This chapter includes hook point and C function reference material that is specific to Momentum 4 Hook points and C functions that are common to Momentum 4 and Momentum 3 are provided in the Momentum 3 x documentation For hook points see the C API For C functions see the..." @@ -11,6 +11,7 @@ description: "This chapter includes hook point and C function reference material |---------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------| | [msg_gen_data_spool](/momentum/4/hooks/msg-gen-data-spool) | This hook is invoked after a message has been generated by the msg_gen module | | [config_rsrc_setup](/momentum/4/hooks/config-rsrc-setup) | Register a resource | +| [core_post_final_validation](/momentum/4/hooks/core-post-final-validation) | Same usage as but invoked right after the `core_final_validation` hook | | [ec_config_rsrc_get](/momentum/4/apis-ec-config-rsrc-get) | Return a resource list blobject from the configuration system | | [ec_httpsrv_register_auth](/momentum/4/apis-ec-httpsrv-register-auth) | Register an HTTP handler for authenticating a URI | | [ec_httpsrv_request_local_address](/momentum/4/apis-ec-httpsrv-request-local-address) | Returns the local IP address from the current session | diff --git a/content/momentum/4/lua/index.md b/content/momentum/4/lua/index.md index aa963d5e9..7fb829e6a 100644 --- a/content/momentum/4/lua/index.md +++ b/content/momentum/4/lua/index.md @@ -191,6 +191,8 @@ description: "This section details all Lua functions Functions are ordered alpha | [msys.tls_params.set](/momentum/4/lua/ref-msys-tls-params-set) | Set a tls parameter string on a per connection basis | | [msys.validate.dk.get_responsible_domain](/momentum/4/lua/ref-msys-validate-dk-get-responsible-domain) | Return the domain responsible for the current message | | [msys.validate.dk.sign](/momentum/4/lua/ref-msys-validate-dk-sign) | Sign a message using a Domain Key | +| [msys.validate.opendarc.sign](/momentum/4/lua/ref-msys-validate-opendarc-sign) | Sign a message using OpenARC | +| [msys.validate.opendarc.verify](/momentum/4/lua/ref-msys-validate-opendarc-verify) | Verify ARC sets | | [msys.validate.opendkim.get_num_sigs](/momentum/4/lua/ref-msys-validate-opendkim-get-num-sigs) | Return the number of DKIM signatures | | [msys.validate.opendkim.get_sig](/momentum/4/lua/ref-msys-validate-opendkim-get-sig) | Get a signature from a DKIM object | | [msys.validate.opendkim.get_sig_canons](/momentum/4/lua/ref-msys-validate-opendkim-get-sig-canons) | Fetch the canonicalizers used for a signature | diff --git a/content/momentum/4/modules/openarc.md b/content/momentum/4/modules/openarc.md index 2c25a1488..c8a65a115 100644 --- a/content/momentum/4/modules/openarc.md +++ b/content/momentum/4/modules/openarc.md @@ -33,13 +33,9 @@ openarc {} The `msys.validate.opendarc.sign` does verification first. You should only invoke one of the APIs, either `verify` or `sign` but not both. -It's recommended to invoke `msys.validate.opendarc.verify` in `validate_data_spool` hook. +It's recommended to invoke `msys.validate.opendarc.verify` in `validate_data_spool` or +[`validate_data_spool_each_rcpt`](/momentum/3/3-api/hooks-core-validate-data-spool-each-rcpt) hook. `msys.validate.opendarc.sign` shall be invoked in the last validation phase, in -`post_final_validation` hook. - -The `post_final_validation` hook is added as the absolute last point before writing the message into -spool. No any message modification expected after this stage. To avoid undefined race between -multiple implementations of the same hook, you shall only have up to one implementation for this -hook. And it's the best place to call `msys.validate.opendarc.sign`. +[`post_final_validation`](/momentum/4/hooks/core-post-final-validate) hook. See API examples for hook usages. diff --git a/content/momentum/4/modules/summary-all-modules.md b/content/momentum/4/modules/summary-all-modules.md index 22031ab1b..cd19e8d15 100644 --- a/content/momentum/4/modules/summary-all-modules.md +++ b/content/momentum/4/modules/summary-all-modules.md @@ -70,6 +70,7 @@ All modules are listed alphabetically with a brief description. Singleton module | [msgc_client](/momentum/4/modules/msgc) (*singleton*) | 4.0 | The client component of MSGC |   |  ✓ |   |   | | [msgc_server](/momentum/4/modules/msgc) (*singleton*) | 4.0 | The server component of MSGC |   |  ✓ |   |   | | [“mxip - IP Addresses In MX Records”](/momentum/4/modules/mxip) | 4.2 | Enable Momentum to deliver to domains with a textual IP address |   |   |   |   | +| [“opendarc – Open Source ARC”](/momentum/4/modules/opendarc) | 5.0 | Validate/sign mail using ARC |   |   |  ✓ |   | | [“opendkim – Open Source DKIM”](/momentum/4/modules/opendkim) | 4.0 | Validate/sign mail using DKIM signatures |   |   |  ✓ |   | | [“outbound_audit – Outbound traffic analytics”](/momentum/4/modules/outbound-audit) | 4.0 | Provides time-series analytics on the behavior of receiving domains |   |  ✓ |   |   | | [“outbound_smtp_auth”](/momentum/4/modules/outbound-smtp-auth) | 4.2 | Enables users to specify authentication parameters for a given set of messages |   |   |   |   | From a8aff23a6867e922c2402ba23a0c14e11865efa2 Mon Sep 17 00:00:00 2001 From: Julie Zhao Date: Tue, 26 Nov 2024 11:15:20 -0500 Subject: [PATCH 05/13] add file --- content/momentum/4/4-lua-summary-table.md | 4 +- .../4/hooks/core-post-final-validation.md | 92 +++++++++++++++++++ content/momentum/4/modules/openarc.md | 2 +- .../momentum/4/modules/summary-all-modules.md | 2 +- 4 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 content/momentum/4/hooks/core-post-final-validation.md diff --git a/content/momentum/4/4-lua-summary-table.md b/content/momentum/4/4-lua-summary-table.md index a427611f4..cf5d4137f 100644 --- a/content/momentum/4/4-lua-summary-table.md +++ b/content/momentum/4/4-lua-summary-table.md @@ -175,7 +175,7 @@ This section contains tables of Lua functions. Click the function name for detai | [msys.validate.dk.get_responsible_domain](/momentum/4/lua/ref-msys-validate-dk-get-responsible-domain) – This function requires module "dk_validate". "msg" is a mail message. "ctx" is the validation context. It returns the responsible domain for the current message | msg, ctx | msys.validate.dk | 4.0 | data, data_spool, data_spool_each_rcpt | | [msys.validate.dk.sign](/momentum/4/lua/ref-msys-validate-dk-sign) – Sign a message using a Domain Key | msg, ctx, options | msys.validate.dk | 4.0 | core_data_validation | | [msys.validate.openarc.sign](/momentum/4/lua/ref-msys-validate-openarc-sign) – Sign a message using OpenARC | msg, options, [ar] | msys.validate.openarc | 5.0 | core_post_final_validation | -| [msys.validate.openarc.verify](/momentum/4/lua/ref-msys-validate-openarc-verify) – Verify ARC sets | m | msys.validate.openarc | 5.0 | data_spool, data_spool_each_rcpt | +| [msys.validate.openarc.verify](/momentum/4/lua/ref-msys-validate-openarc-verify) – Verify ARC sets | msg | msys.validate.openarc | 5.0 | data_spool, data_spool_each_rcpt | | [msys.validate.opendkim.get_num_sigs](/momentum/4/lua/ref-msys-validate-opendkim-get-num-sigs) – Return the number of DKIM signatures | dkim | msys.validate.opendkim | 4.0 | data, data_spool, data_spool_each_rcpt | | [msys.validate.opendkim.get_sig](/momentum/4/lua/ref-msys-validate-opendkim-get-sig) – Get a signature from a DKIM object | dkim, [num] | msys.validate.opendkim | 4.0 | data, data_spool, data_spool_each_rcpt | | [msys.validate.opendkim.get_sig_canons](/momentum/4/lua/ref-msys-validate-opendkim-get-sig-canons) – Fetch the canonicalizers used for a DKIM signature | dkim_sig | msys.validate.opendkim | 4.0 | data, data_spool, data_spool_each_rcpt | @@ -188,7 +188,7 @@ This section contains tables of Lua functions. Click the function name for detai | [msys.validate.opendkim.get_sig_selector](/momentum/4/lua/ref-msys-validate-opendkim-get-sig-selector) – Fetch the selector associated with a DKIM signature | dkim_sig | msys.validate.opendkim | 4.0 | data, data_spool, data_spool_each_rcpt | | [msys.validate.opendkim.get_sig_signalg](/momentum/4/lua/ref-msys-validate-opendkim-get-sig-signalg) – Return the signing algorithm as a string | dkim_sig | msys.validate.opendkim | 4.0 | data, data_spool, data_spool_each_rcpt | | [msys.validate.opendkim.sign](/momentum/4/lua/ref-msys-validate-opendkim-sign) – Sign a message using OpenDKIM | msg, vctx, [options] | msys.validate.opendkim | 4.0 | core_final_validation | -| [msys.validate.opendkim.verify](/momentum/4/lua/ref-msys-validate-opendkim-verify) – Verify an DKIM signature | m | msys.validate.opendkim | 4.0 | data, data_spool, data_spool_each_rcpt | +| [msys.validate.opendkim.verify](/momentum/4/lua/ref-msys-validate-opendkim-verify) – Verify an DKIM signature | msg | msys.validate.opendkim | 4.0 | data, data_spool, data_spool_each_rcpt | | [sess:request_add_header](/momentum/4/lua/ref-sess-request-add-header) – Set the header of an HTTP session | header, value, replace | msys.httpclnt | 4.0 | http_request_eval | | [sess:request_delete_header](/momentum/4/lua/ref-sess-request-delete-header) – Delete a header from an HTTP session | header | msys.httpclnt | 4.0 | http_request_eval | | [sess:request_finalize](/momentum/4/lua/ref-sess-request-finalize) – Finalize changes to an HTTP request | update | msys.httpclnt | 4.0 | http_request_eval | diff --git a/content/momentum/4/hooks/core-post-final-validation.md b/content/momentum/4/hooks/core-post-final-validation.md new file mode 100644 index 000000000..341271bdf --- /dev/null +++ b/content/momentum/4/hooks/core-post-final-validation.md @@ -0,0 +1,92 @@ +--- +lastUpdated: "11/26/2024" +title: "post_final_validation" +description: "hook invoked after the normal final validation" +--- + + +## Name + +post_final_validation — This hook is invoked after the normal +[final_validation](/momentum/3/3-api/hooks-core-final-validation) hook + +## Synopsis + +`#include "hooks/core/final_validation.h"` + +| `int **core_post_final_validation** (` | closure, |   | +|   | msg, |   | +|   | ac, |   | +|   | ctx`)`; |   | + +`void * closure`; +`ec_message * msg`; +`accept_construct * ac`; +`validate_context * ctx`; + + +## Description + +This hook is invoked right after the +[final_validation](/momentum/3/3-api/hooks-core-final-validation) hook is called. Its return value +does not have significance for now. +This hook is added as the absolute last point before writing the message into spool. +It guarantees that operations implemented in this hook will happen after the operations done in +`final_validtion`. +No any message modification expected after this stage. +To avoid undefined race between multiple implementations of the same hook, you shall only have up +to one implementation for this hook. +It's the recommended hook point for ARC signing/sealing. + + +**Parameters** + +The parameters from this hook are the same as the ones for `final_validation` hook. + +
+ +
closure
+ +
+ +A pointer to the closure function. + +
+ +
msg
+ +
+ +A pointer to an ec_message struct. For documentation of this data structure see [“ec_message”](/momentum/3/3-api/structs-ec-message) + +
+ +
ac
+ +
+ +The `accept_construct` struct. For documentation of this data structure see [“accept_construct”](/momentum/3/3-api/structs-accept-construct) + +
+ +
ctx
+ +
+ +The `validate_context` struct. For documentation of this data structure see [“validate_context”](/momentum/3/3-api/structs-validate-context) + +
+ +
+ +**Return Values** + +This hook returns `int`, but for now has no significance, i.e. the return value is not checked in +the caller. + +**Threading** + +This hook will be called in any thread. + + + diff --git a/content/momentum/4/modules/openarc.md b/content/momentum/4/modules/openarc.md index c8a65a115..de5956653 100644 --- a/content/momentum/4/modules/openarc.md +++ b/content/momentum/4/modules/openarc.md @@ -36,6 +36,6 @@ The `msys.validate.opendarc.sign` does verification first. You should only invok It's recommended to invoke `msys.validate.opendarc.verify` in `validate_data_spool` or [`validate_data_spool_each_rcpt`](/momentum/3/3-api/hooks-core-validate-data-spool-each-rcpt) hook. `msys.validate.opendarc.sign` shall be invoked in the last validation phase, in -[`post_final_validation`](/momentum/4/hooks/core-post-final-validate) hook. +[`post_final_validation`](/momentum/4/hooks/core-post-final-validation) hook. See API examples for hook usages. diff --git a/content/momentum/4/modules/summary-all-modules.md b/content/momentum/4/modules/summary-all-modules.md index cd19e8d15..71b587077 100644 --- a/content/momentum/4/modules/summary-all-modules.md +++ b/content/momentum/4/modules/summary-all-modules.md @@ -70,7 +70,7 @@ All modules are listed alphabetically with a brief description. Singleton module | [msgc_client](/momentum/4/modules/msgc) (*singleton*) | 4.0 | The client component of MSGC |   |  ✓ |   |   | | [msgc_server](/momentum/4/modules/msgc) (*singleton*) | 4.0 | The server component of MSGC |   |  ✓ |   |   | | [“mxip - IP Addresses In MX Records”](/momentum/4/modules/mxip) | 4.2 | Enable Momentum to deliver to domains with a textual IP address |   |   |   |   | -| [“opendarc – Open Source ARC”](/momentum/4/modules/opendarc) | 5.0 | Validate/sign mail using ARC |   |   |  ✓ |   | +| [“openarc – Open Source ARC”](/momentum/4/modules/openarc) | 5.0 | Validate/sign mail using ARC |   |   |  ✓ |   | | [“opendkim – Open Source DKIM”](/momentum/4/modules/opendkim) | 4.0 | Validate/sign mail using DKIM signatures |   |   |  ✓ |   | | [“outbound_audit – Outbound traffic analytics”](/momentum/4/modules/outbound-audit) | 4.0 | Provides time-series analytics on the behavior of receiving domains |   |  ✓ |   |   | | [“outbound_smtp_auth”](/momentum/4/modules/outbound-smtp-auth) | 4.2 | Enables users to specify authentication parameters for a given set of messages |   |   |   |   | From 834e91eb0baf7915b811a131daffd46fda3e3012 Mon Sep 17 00:00:00 2001 From: Julie Zhao Date: Tue, 26 Nov 2024 12:52:31 -0500 Subject: [PATCH 06/13] more cleanup --- .../4/hooks/core-post-final-validation.md | 14 ++----- .../4/lua/ref-msys-validate-openarc-sign.md | 37 +++++++++++++------ .../4/lua/ref-msys-validate-openarc-verify.md | 6 +-- 3 files changed, 32 insertions(+), 25 deletions(-) diff --git a/content/momentum/4/hooks/core-post-final-validation.md b/content/momentum/4/hooks/core-post-final-validation.md index 341271bdf..00820b230 100644 --- a/content/momentum/4/hooks/core-post-final-validation.md +++ b/content/momentum/4/hooks/core-post-final-validation.md @@ -14,21 +14,13 @@ post_final_validation — This hook is invoked after the normal `#include "hooks/core/final_validation.h"` -| `int **core_post_final_validation** (` | closure, |   | -|   | msg, |   | -|   | ac, |   | -|   | ctx`)`; |   | - -`void * closure`; -`ec_message * msg`; -`accept_construct * ac`; -`validate_context * ctx`; +`int core_post_final_validation(void closure, ec_message *msg, accept_construct *ac, valiate_context *ctx)` ## Description This hook is invoked right after the -[final_validation](/momentum/3/3-api/hooks-core-final-validation) hook is called. Its return value +[final_validation](/momentum/3/3-api/hooks-core-final-validation) hook. Its return value does not have significance for now. This hook is added as the absolute last point before writing the message into spool. It guarantees that operations implemented in this hook will happen after the operations done in @@ -81,7 +73,7 @@ The `validate_context` struct. For documentation of this data structure see [“ **Return Values** -This hook returns `int`, but for now has no significance, i.e. the return value is not checked in +This hook returns `int`, but for now the return value has no significance, i.e. it is not checked in the caller. **Threading** diff --git a/content/momentum/4/lua/ref-msys-validate-openarc-sign.md b/content/momentum/4/lua/ref-msys-validate-openarc-sign.md index 22fbbd379..9b26b1f89 100644 --- a/content/momentum/4/lua/ref-msys-validate-openarc-sign.md +++ b/content/momentum/4/lua/ref-msys-validate-openarc-sign.md @@ -18,8 +18,7 @@ msys.validate.openarc.seal - synonym of `msys.validation.openarc.sign`. ``` msg: userdata, ec_message type options: table -ar: string, optional. It's the message's authentication assessment to be enshrined into the AAR -(ARC-Authentication-Results) header. +ar: string, optional. It's the message's authentication assessment to be enshrined into the AAR header. ``` @@ -27,7 +26,8 @@ ar: string, optional. It's the message's authentication assessment to be enshrin This function does ARC validation first, then combine the validation result with authentication assessments from other methods (e.g. SPF, DKIM, etc) defined by the `ar` and put it into the AAR -header; then sign and seal the message by adding the AMS (ARC-Message-Signature) and AS +(ARC-Authentication-Results) header; + then sign and seal the message by adding the AMS (ARC-Message-Signature) and AS (ARC-Seal) headers, using the signing mechanism defined in the `options` table. This function requires the [`openarc`](/momentum/4/modules/openarc) module. @@ -47,11 +47,19 @@ This function takes the following parameters: * `authservid` – authentication service identifier, as [authserv-id](https://datatracker.ietf.org/doc/html/rfc8601#section-2.5) defined in RFC. - * `header_canon` – header canonicalization setting + If not set, will be default to the hostname. + + * `header_canon` – header canonicalization setting. + + Supported values are `relaxed`, `simple`. Default to `relaxed`. * `body_canon` – body canonicalization setting - * `digest` – signing algorithm digest setting + Supported values are `relaxed`, `simple`. Default to `relaxed`. + + * `digest` – signing algorithm digest setting. + + Supported values are `rsa-sha1` and `rsa-sha256`. Default to `rsa-sha256`. * `keyfile` – signing key file @@ -64,11 +72,16 @@ This function takes the following parameters: If not defined, will be built from the `keyfile`. - * `headerlist` – ";" separated list of headers to sign + * `headerlist` – "`;`" separated list of headers to sign - * `oversign_headerlist` – ";" seperated list of headers for over signing + * `oversign_headerlist` – "`;`" seperated list of headers for over signing -* `ar` - authentication assessment to be enshrined in the AAR (ARC-Authentication-Results) header. + * `skip_ar_header_update` – if set, no update to the AR (Authentication-Results) header. + + If not set, Momentum will append the ARC verification result (e.g. `arc=pass`) to + the existing AR header or create one if it does not exist. + +* `ar` - authentication assessment to be enshrined into the AAR (ARC-Authentication-Results) header. If not provided, Momentum will take the value from the existing `Authentication-Results` header. Momentum appends this value with the ARC verification result (e.g. `arc=pass`) and use it to @@ -80,6 +93,9 @@ This function takes the following parameters: Since ARC sealing should happen after all potential modification of a message is done, this function shall be invoked in the `post_final_validation` stage after all the other validation phases. +If for any reason the ARC signing/sealing failed, the context variable `arc_cv` of the `ec_message` +will not be set, and the error reason is logged into paniclog. + ### Example @@ -87,8 +103,7 @@ shall be invoked in the `post_final_validation` stage after all the other valida ``` require("msys.core"); -require("msys.extended.message"); -local openarc = require("msys.validate.openarc"); +require("msys.validate.openarc"); local mod = {}; function mod:core_post_final_validation(msg, accept, vctx) @@ -99,7 +114,7 @@ function mod:core_post_final_validation(msg, accept, vctx) sealer.headerlist = "From:Subject:Date:To:MIME-Version:Content-Type" sealer.oversign_headerlist = "From:To:Subject" - openarc.sign(msg, sealer) + msys.validate.openarc.sign(msg, sealer) end msys.registerModule("openarc_sign", mod); diff --git a/content/momentum/4/lua/ref-msys-validate-openarc-verify.md b/content/momentum/4/lua/ref-msys-validate-openarc-verify.md index 3b6ed25a1..ff855d457 100644 --- a/content/momentum/4/lua/ref-msys-validate-openarc-verify.md +++ b/content/momentum/4/lua/ref-msys-validate-openarc-verify.md @@ -41,11 +41,11 @@ which would not block Momentum's main tasks, e.g. from the `validate_data_spool` ``` require("msys.core"); require("msys.extended.message"); -local openarc = require("msys.validate.openarc"); +require("msys.validate.openarc"); local mod = {}; -function mod:mod:validate_data_spool(msg, ac, vctx) - openarc.verify(msg) +function mod:validate_data_spool(msg, ac, vctx) + msys.validate.openarc.verify(msg) local cv = msg:context_get(msys.core.ECMESS_CTX_MESS, "arc_cv") if cv then print("ARC validation result: ", cv) From cab6648b0416058dc3a4c364568fc6c54ba79293 Mon Sep 17 00:00:00 2001 From: Julie Zhao Date: Thu, 5 Dec 2024 16:04:51 -0500 Subject: [PATCH 07/13] review --- content/momentum/4/4-lua-summary-table.md | 2 +- .../4/hooks/core-post-final-validation.md | 12 +++--- content/momentum/4/lua/index.md | 6 +-- .../4/lua/ref-msys-validate-openarc-sign.md | 40 ++++++++++++------- .../4/lua/ref-msys-validate-openarc-verify.md | 8 ++-- content/momentum/4/modules/index.md | 2 +- content/momentum/4/modules/openarc.md | 19 ++++++--- .../momentum/4/modules/summary-all-modules.md | 2 +- 8 files changed, 54 insertions(+), 37 deletions(-) diff --git a/content/momentum/4/4-lua-summary-table.md b/content/momentum/4/4-lua-summary-table.md index cf5d4137f..6a72e51dc 100644 --- a/content/momentum/4/4-lua-summary-table.md +++ b/content/momentum/4/4-lua-summary-table.md @@ -1,5 +1,5 @@ --- -lastUpdated: "10/05/2021" +lastUpdated: "12/01/2024" title: "Lua Functions Summary" description: "This section contains tables of Lua functions Click the function name for details Table 64 1 Lua functions all Function Description Params Package Version Phases ac esmtp capability add Add a capability to the EHLO response name msys extended ac 4 0 connect ehlo ac esmtp capability remove Removes a..." --- diff --git a/content/momentum/4/hooks/core-post-final-validation.md b/content/momentum/4/hooks/core-post-final-validation.md index 00820b230..61fec6cfc 100644 --- a/content/momentum/4/hooks/core-post-final-validation.md +++ b/content/momentum/4/hooks/core-post-final-validation.md @@ -22,13 +22,13 @@ post_final_validation — This hook is invoked after the normal This hook is invoked right after the [final_validation](/momentum/3/3-api/hooks-core-final-validation) hook. Its return value does not have significance for now. -This hook is added as the absolute last point before writing the message into spool. +This hook is added as the absolute last point before writing the message to spool for delivery. It guarantees that operations implemented in this hook will happen after the operations done in -`final_validtion`. -No any message modification expected after this stage. -To avoid undefined race between multiple implementations of the same hook, you shall only have up -to one implementation for this hook. -It's the recommended hook point for ARC signing/sealing. +`final_validation`. +No message modification is expected after this stage. +To avoid undefined ordering between multiple implementations of the same hook, you shall have at most + one implementation for this hook. +> It's the recommended hook point for ARC signing/sealing. **Parameters** diff --git a/content/momentum/4/lua/index.md b/content/momentum/4/lua/index.md index 7fb829e6a..bc546c999 100644 --- a/content/momentum/4/lua/index.md +++ b/content/momentum/4/lua/index.md @@ -1,5 +1,5 @@ --- -lastUpdated: "10/05/2021" +lastUpdated: "12/01/2024" title: "Category File" type: "custom" name: "Lua Functions Reference" @@ -191,8 +191,8 @@ description: "This section details all Lua functions Functions are ordered alpha | [msys.tls_params.set](/momentum/4/lua/ref-msys-tls-params-set) | Set a tls parameter string on a per connection basis | | [msys.validate.dk.get_responsible_domain](/momentum/4/lua/ref-msys-validate-dk-get-responsible-domain) | Return the domain responsible for the current message | | [msys.validate.dk.sign](/momentum/4/lua/ref-msys-validate-dk-sign) | Sign a message using a Domain Key | -| [msys.validate.opendarc.sign](/momentum/4/lua/ref-msys-validate-opendarc-sign) | Sign a message using OpenARC | -| [msys.validate.opendarc.verify](/momentum/4/lua/ref-msys-validate-opendarc-verify) | Verify ARC sets | +| [msys.validate.openarc.sign](/momentum/4/lua/ref-msys-validate-openarc-sign) | Sign a message using OpenARC | +| [msys.validate.openarc.verify](/momentum/4/lua/ref-msys-validate-openarc-verify) | Verify ARC sets | | [msys.validate.opendkim.get_num_sigs](/momentum/4/lua/ref-msys-validate-opendkim-get-num-sigs) | Return the number of DKIM signatures | | [msys.validate.opendkim.get_sig](/momentum/4/lua/ref-msys-validate-opendkim-get-sig) | Get a signature from a DKIM object | | [msys.validate.opendkim.get_sig_canons](/momentum/4/lua/ref-msys-validate-opendkim-get-sig-canons) | Fetch the canonicalizers used for a signature | diff --git a/content/momentum/4/lua/ref-msys-validate-openarc-sign.md b/content/momentum/4/lua/ref-msys-validate-openarc-sign.md index 9b26b1f89..f9584374b 100644 --- a/content/momentum/4/lua/ref-msys-validate-openarc-sign.md +++ b/content/momentum/4/lua/ref-msys-validate-openarc-sign.md @@ -13,12 +13,14 @@ msys.validate.openarc.seal - synonym of `msys.validation.openarc.sign`. ## Synopsis -`msys.validate.openarc.verify(msg, options, ar)` +`msys.validate.openarc.sign(msg, options, ar)` + +`msys.validate.openarc.seal(msg, options, ar)` ``` msg: userdata, ec_message type options: table -ar: string, optional. It's the message's authentication assessment to be enshrined into the AAR header. +ar: string, optional. It's the message's authentication assessment to be copied as-is into the AAR header. ``` @@ -47,19 +49,19 @@ This function takes the following parameters: * `authservid` – authentication service identifier, as [authserv-id](https://datatracker.ietf.org/doc/html/rfc8601#section-2.5) defined in RFC. - If not set, will be default to the hostname. + If not set, will be defaulted to the hostname. * `header_canon` – header canonicalization setting. - Supported values are `relaxed`, `simple`. Default to `relaxed`. + Supported values are `relaxed`, `simple`. Defaults to `relaxed`. * `body_canon` – body canonicalization setting - Supported values are `relaxed`, `simple`. Default to `relaxed`. + Supported values are `relaxed`, `simple`. Defaults to `relaxed`. * `digest` – signing algorithm digest setting. - Supported values are `rsa-sha1` and `rsa-sha256`. Default to `rsa-sha256`. + Supported values are `rsa-sha1` and `rsa-sha256`. Defaults to `rsa-sha256`. * `keyfile` – signing key file @@ -72,32 +74,32 @@ This function takes the following parameters: If not defined, will be built from the `keyfile`. - * `headerlist` – "`;`" separated list of headers to sign + * `headerlist` – colon-separated list of headers to sign - * `oversign_headerlist` – "`;`" seperated list of headers for over signing + * `oversign_headerlist` – colon-separated list of headers for over signing * `skip_ar_header_update` – if set, no update to the AR (Authentication-Results) header. If not set, Momentum will append the ARC verification result (e.g. `arc=pass`) to the existing AR header or create one if it does not exist. -* `ar` - authentication assessment to be enshrined into the AAR (ARC-Authentication-Results) header. +* `ar` - authentication assessment to be copied as-is into the AAR (ARC-Authentication-Results) header. If not provided, Momentum will take the value from the existing `Authentication-Results` header. - Momentum appends this value with the ARC verification result (e.g. `arc=pass`) and use it to + Momentum appends this value with the ARC verification result (e.g. `arc=pass`) and uses it to build the AAR header. ### Note -Since ARC sealing should happen after all potential modification of a message is done, this function -shall be invoked in the `post_final_validation` stage after all the other validation phases. +Since ARC sealing must not happen until all potential modification of a message is done, this function + should be invoked in the `post_final_validation` stage after all the other validation phases. -If for any reason the ARC signing/sealing failed, the context variable `arc_cv` of the `ec_message` +If for any reason the ARC signing/sealing failed, the context variable `arc_seal` of the `ec_message` will not be set, and the error reason is logged into paniclog. - + ### Example @@ -115,6 +117,14 @@ function mod:core_post_final_validation(msg, accept, vctx) sealer.oversign_headerlist = "From:To:Subject" msys.validate.openarc.sign(msg, sealer) + + -- check sign/seal result + local ok = msg:context_get(msys.core.ECMESS_CTX_MESS, "arc_seal") + if ok == nil or ok == '' then + print("ARC seal failed. No ARC set add! Check paniclog for reasons.") + else + print("ARC seal ok. ARC set added!") + end end msys.registerModule("openarc_sign", mod); @@ -122,4 +132,4 @@ msys.registerModule("openarc_sign", mod); ## See Also -[msys.validate.opendarc.verify](/momentum/4/lua/ref-msys-validate-openarc-verify) +[msys.validate.openarc.verify](/momentum/4/lua/ref-msys-validate-openarc-verify) diff --git a/content/momentum/4/lua/ref-msys-validate-openarc-verify.md b/content/momentum/4/lua/ref-msys-validate-openarc-verify.md index ff855d457..dddcd7ad3 100644 --- a/content/momentum/4/lua/ref-msys-validate-openarc-verify.md +++ b/content/momentum/4/lua/ref-msys-validate-openarc-verify.md @@ -7,7 +7,7 @@ description: "msys validate openarc verify Verify ARC sets headers" ## Name -msys.validate.openarc.verify — Verifies ARC set headers in an email, stores the verification results +msys.validate.openarc.verify — Verifies ARC set headers in an email, and stores the verification results (`none/pass/fail`) into the email's context variable. ## Synopsis @@ -29,12 +29,12 @@ Enable this function with the statement `require('msys.validate.openarc')`. ### Note If the `ec_message` context variable `arc_cv` is not set after this function call, errors happened -and logged into paniclog. +and were logged into paniclog. This function invokes dns lookup for signature validation. It's recommended to invoke it from a hook which would not block Momentum's main tasks, e.g. from the `validate_data_spool` hook. - + ### Example @@ -59,4 +59,4 @@ msys.registerModule("openarc_verify", mod); ## See Also -[msys.validate.opendarc.sign](/momentum/4/lua/ref-msys-validate-openarc-sign) +[msys.validate.openarc.sign](/momentum/4/lua/ref-msys-validate-openarc-sign) diff --git a/content/momentum/4/modules/index.md b/content/momentum/4/modules/index.md index e21809faa..ed9d2ed06 100644 --- a/content/momentum/4/modules/index.md +++ b/content/momentum/4/modules/index.md @@ -1,5 +1,5 @@ --- -lastUpdated: "10/05/2021" +lastUpdated: "12/01/2024" title: "Category File" type: "custom" name: "Modules Reference" diff --git a/content/momentum/4/modules/openarc.md b/content/momentum/4/modules/openarc.md index de5956653..6a37b1ea1 100644 --- a/content/momentum/4/modules/openarc.md +++ b/content/momentum/4/modules/openarc.md @@ -9,7 +9,7 @@ ARC is an acronym for Authenticated Received Chain. It’s a technology protocol custody" for a message, allowing each entity that handles the message to see what entities handled it before and what the message's authentication assessment was at each step in the handling flow. -The openarc module add ARC capability to Momentum. It provides Lua APIs for +The openarc module adds ARC capability to Momentum. It provides Lua and C APIs for ARC validation on a received email, and ARC siging and sealing on an outgoing email. When the module is enabled, ARC validation and signing/sealing can be achieved through calling these APIs from hook policies. @@ -24,18 +24,25 @@ openarc {} ### Lua APIs and examples -[msys.validate.opendarc.verify](/momentum/4/lua/ref-msys-validate-openarc-verify) +[msys.validate.openarc.verify](/momentum/4/lua/ref-msys-validate-openarc-verify) -[msys.validate.opendarc.sign](/momentum/4/lua/ref-msys-validate-openarc-sign) +[msys.validate.openarc.sign](/momentum/4/lua/ref-msys-validate-openarc-sign) + + +### C APIs + +All the related C structures and C API functions are defined in the header file + `validate/openarc.h`. Please refer to the header file for the usage of the C structures and + functions. Please contact support if further assistance is needed. ### Hook points to invoke the APIs -The `msys.validate.opendarc.sign` does verification first. You should only invoke one of the APIs, +The `msys.validate.openarc.sign` does verification first. You should only invoke one of the APIs, either `verify` or `sign` but not both. -It's recommended to invoke `msys.validate.opendarc.verify` in `validate_data_spool` or +It's recommended to invoke `msys.validate.openarc.verify` in `validate_data_spool` or [`validate_data_spool_each_rcpt`](/momentum/3/3-api/hooks-core-validate-data-spool-each-rcpt) hook. -`msys.validate.opendarc.sign` shall be invoked in the last validation phase, in +`msys.validate.openarc.sign` shall be invoked in the last validation phase, in [`post_final_validation`](/momentum/4/hooks/core-post-final-validation) hook. See API examples for hook usages. diff --git a/content/momentum/4/modules/summary-all-modules.md b/content/momentum/4/modules/summary-all-modules.md index 71b587077..24354a453 100644 --- a/content/momentum/4/modules/summary-all-modules.md +++ b/content/momentum/4/modules/summary-all-modules.md @@ -1,5 +1,5 @@ --- -lastUpdated: "03/26/2020" +lastUpdated: "12/01/2024" title: "Modules Summary" description: "All modules are listed alphabetically with a brief description Singleton modules are also identified The Version column indicates when the module was introduced into the system Note all modules listed as 4 0 modules were actually introduced in prior versions of Momentum The Auto column indicates whether a module is..." --- From 0a3c0b27f9cfcc6716e2ef948cc620d312b8e0d9 Mon Sep 17 00:00:00 2001 From: Julie Zhao Date: Thu, 5 Dec 2024 16:56:21 -0500 Subject: [PATCH 08/13] minor update --- content/momentum/4/modules/openarc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/momentum/4/modules/openarc.md b/content/momentum/4/modules/openarc.md index 6a37b1ea1..2f75eff6f 100644 --- a/content/momentum/4/modules/openarc.md +++ b/content/momentum/4/modules/openarc.md @@ -32,7 +32,7 @@ openarc {} ### C APIs All the related C structures and C API functions are defined in the header file - `validate/openarc.h`. Please refer to the header file for the usage of the C structures and + `validate/ec_openarc.h`. Please refer to the header file for the usage of the C structures and functions. Please contact support if further assistance is needed. From 5b83e4419f88a2464d94659f14197f5ce8d44690 Mon Sep 17 00:00:00 2001 From: Julie Zhao Date: Fri, 13 Dec 2024 16:00:34 -0500 Subject: [PATCH 09/13] remove the clause causing confusion --- content/momentum/4/hooks/core-post-final-validation.md | 1 - 1 file changed, 1 deletion(-) diff --git a/content/momentum/4/hooks/core-post-final-validation.md b/content/momentum/4/hooks/core-post-final-validation.md index 61fec6cfc..0af6da8f5 100644 --- a/content/momentum/4/hooks/core-post-final-validation.md +++ b/content/momentum/4/hooks/core-post-final-validation.md @@ -25,7 +25,6 @@ does not have significance for now. This hook is added as the absolute last point before writing the message to spool for delivery. It guarantees that operations implemented in this hook will happen after the operations done in `final_validation`. -No message modification is expected after this stage. To avoid undefined ordering between multiple implementations of the same hook, you shall have at most one implementation for this hook. > It's the recommended hook point for ARC signing/sealing. From 7b02e78df2247989e87c661e17c946068cb685e4 Mon Sep 17 00:00:00 2001 From: Julie Zhao Date: Fri, 3 Jan 2025 14:17:00 -0500 Subject: [PATCH 10/13] update to allow message modification between ARC verify and sign. Adding Lua examples --- .../4/lua/ref-msys-validate-openarc-sign.md | 32 ++-- .../4/lua/ref-msys-validate-openarc-verify.md | 9 +- content/momentum/4/modules/openarc.md | 143 ++++++++++++++++-- 3 files changed, 161 insertions(+), 23 deletions(-) diff --git a/content/momentum/4/lua/ref-msys-validate-openarc-sign.md b/content/momentum/4/lua/ref-msys-validate-openarc-sign.md index f9584374b..aac0b4fc3 100644 --- a/content/momentum/4/lua/ref-msys-validate-openarc-sign.md +++ b/content/momentum/4/lua/ref-msys-validate-openarc-sign.md @@ -26,11 +26,14 @@ ar: string, optional. It's the message's authentication assessment to be copied ## Description -This function does ARC validation first, then combine the validation result with authentication -assessments from other methods (e.g. SPF, DKIM, etc) defined by the `ar` and put it into the AAR -(ARC-Authentication-Results) header; - then sign and seal the message by adding the AMS (ARC-Message-Signature) and AS -(ARC-Seal) headers, using the signing mechanism defined in the `options` table. +This function acquires ARC chain status (i.e. `cv`) from `ec_message` context variable `arc_cv`. The `cv` + will be used in the AS (ARC-Seal) header, and combined with authentication assessments from other + methods (e.g. SPF, DKIM, etc) defined by the `ar` and put into the AAR (ARC-Authentication-Results) + header. This function signs and seals the message by adding the AMS (ARC-Message-Signature) and AS + (ARC-Seal) headers, using the signing mechanism defined in the `options` table. + +If `ec_message` context variable `arc_cv` is not set when the function is called, the function will do an + internal ARC validation (to set the `arc_cv`), followed by the regular `cv` based signing. This function requires the [`openarc`](/momentum/4/modules/openarc) module. @@ -92,11 +95,20 @@ This function takes the following parameters: ### Note -Since ARC sealing must not happen until all potential modification of a message is done, this function - should be invoked in the `post_final_validation` stage after all the other validation phases. +Since ARC sealing must not happen until all potential modification of a message is done, if you + already have implementations in some other validation phases/hooks, this function + should be invoked in the `post_final_validation` stage to guarantee that it is called + after all the other hook implementations. + +The function would cause the `ec_message` context variable `arc_seal` to be set: + +`ok`: ARC signing/sealing is done, and ARC set headers are added + +`skip`: ARC signing/sealing is skipped, because the ARC chain already fails before reaching the + current MTA. -If for any reason the ARC signing/sealing failed, the context variable `arc_seal` of the `ec_message` -will not be set, and the error reason is logged into paniclog. +If the context variable `arc_seal` of the `ec_message` is not set, it indicates an unexpected ARC + signing/sealing failure, e.g. due to mis-configuration. The error reason is logged in paniclog. @@ -122,6 +134,8 @@ function mod:core_post_final_validation(msg, accept, vctx) local ok = msg:context_get(msys.core.ECMESS_CTX_MESS, "arc_seal") if ok == nil or ok == '' then print("ARC seal failed. No ARC set add! Check paniclog for reasons.") + elseif ok == "skip" then + print("ARC seal skipped. No ARC set add: ARC chain failed before reaching me.") else print("ARC seal ok. ARC set added!") end diff --git a/content/momentum/4/lua/ref-msys-validate-openarc-verify.md b/content/momentum/4/lua/ref-msys-validate-openarc-verify.md index dddcd7ad3..aa67dd306 100644 --- a/content/momentum/4/lua/ref-msys-validate-openarc-verify.md +++ b/content/momentum/4/lua/ref-msys-validate-openarc-verify.md @@ -28,11 +28,12 @@ Enable this function with the statement `require('msys.validate.openarc')`. ### Note -If the `ec_message` context variable `arc_cv` is not set after this function call, errors happened -and were logged into paniclog. +After being called, this function always sets the `ec_message` context variable `arc_cv` to one of + the values: `none`, `pass`, `fail`. Unexpected `fail` cases are logged into paniclog. This function invokes dns lookup for signature validation. It's recommended to invoke it from a hook -which would not block Momentum's main tasks, e.g. from the `validate_data_spool` hook. +which would not block Momentum's main tasks, e.g. from the `validate_data_spool` or the + `validate_data_spool_each_rcpt` hook. ### Example @@ -44,7 +45,7 @@ require("msys.extended.message"); require("msys.validate.openarc"); local mod = {}; -function mod:validate_data_spool(msg, ac, vctx) +function mod:validate_data_spool_each_rcpt(msg, ac, vctx) msys.validate.openarc.verify(msg) local cv = msg:context_get(msys.core.ECMESS_CTX_MESS, "arc_cv") if cv then diff --git a/content/momentum/4/modules/openarc.md b/content/momentum/4/modules/openarc.md index 2f75eff6f..f764e050a 100644 --- a/content/momentum/4/modules/openarc.md +++ b/content/momentum/4/modules/openarc.md @@ -14,7 +14,7 @@ ARC validation on a received email, and ARC siging and sealing on an outgoing em When the module is enabled, ARC validation and signing/sealing can be achieved through calling these APIs from hook policies. -### Configuration +## Configuration You need to enable the openarc module in the ecelerity configuration file to use the feature: @@ -22,27 +22,150 @@ You need to enable the openarc module in the ecelerity configuration file to use openarc {} ``` -### Lua APIs and examples +The only configuration option available to the `openarc` module is `debug_level`. + + +## Lua APIs and examples [msys.validate.openarc.verify](/momentum/4/lua/ref-msys-validate-openarc-verify) [msys.validate.openarc.sign](/momentum/4/lua/ref-msys-validate-openarc-sign) -### C APIs +## C APIs All the related C structures and C API functions are defined in the header file `validate/ec_openarc.h`. Please refer to the header file for the usage of the C structures and functions. Please contact support if further assistance is needed. -### Hook points to invoke the APIs +## Hook points to invoke the APIs -The `msys.validate.openarc.sign` does verification first. You should only invoke one of the APIs, - either `verify` or `sign` but not both. -It's recommended to invoke `msys.validate.openarc.verify` in `validate_data_spool` or +Invoke `msys.validate.openarc.verify` to do ARC verification on a received message. It would verify +the existing ARC headers, including the AS (ARC Seal) and the AMS (ARC Message Signature). ARC +verification shall be done before any potential message modifications, in `validate_data_spool` or [`validate_data_spool_each_rcpt`](/momentum/3/3-api/hooks-core-validate-data-spool-each-rcpt) hook. -`msys.validate.openarc.sign` shall be invoked in the last validation phase, in -[`post_final_validation`](/momentum/4/hooks/core-post-final-validation) hook. -See API examples for hook usages. +Invoke `msys.validate.openarc.sign` to do ARC signing/sealing to add the ARC headers. It should + happen after all possible message modifications are done, in the regular + [`final_validation`](/momentum/3/3-api/hooks-core-final-validation) hook, or the new + [`post_final_validation`](/momentum/4/hooks/core-post-final-validation) hook. + Any message modification after `msys.validate.openarc.sign` is called can break the integrity of + the ARC headers added during ARC signing. + +Since ARC signing requires the ARC chain verification result (aka `cv`). `msys.validate.openarc.sign` + will get the `cv` value from the `ec_message` context variable `arc_cv` for signing. If `arc_cv` is not + set, indicating a not-yet-done ARC verification, `msys.validate.openarc.sign` will do ARC verification + implicitly. + +If message modification is expected, an MTA shall call `msys.validate.openarc.verify` first (to get + `arc_cv` set) and then `msys.validate.openarc.sign` later in a different hooks, as recommended above. + +If there is absolutely no message modification, e.g. for a passthrough MTA which doesn't alter the +message other than ARC signing, calling `msys.validate.openarc.sign` alone can have some performance +benefits: the message will be scanned once for both ARC verification and signing. + +### Example 1: an intermediate MTA does ARC signing, which can potentially modify the email, e.g. + through DKIM signing, engagement tracking insertion and modification, etc. In such case, ARC verify + needs to happen first, and ARC sign later. + +``` +require("msys.core"); +require("msys.extended.message"); +require("msys.validate.openarc"); +local mod = {}; + +function mod:validate_data_spool(msg, ac, vctx) + -- do ARC verify + msys.validate.openarc.verify(msg) + local cv = msg:context_get(msys.core.ECMESS_CTX_MESS, "arc_cv") + if cv then + print("ARC validation result: ", cv) + else + print("Failed to do ARC validation. Check paniclog for reasons.") + end +end + +function mod:core_final_validation(msg, accept, vctx) + -- do DKIM signing + local base_domain = 'ectest.example.com'; + local header_canon = 'relaxed'; + local body_canon = 'relaxed'; + local digest = 'rsa-sha1'; + local identity = '\@ectest.example.com'; + local selector = 'dkim-s1024'; + local key_file = '/opt/msys/ecelerity/etc/conf/default/dk/ectest.example.com/dkim-s1024.key'; + local body_length_limit = 0; + + local options = {}; + options["base_domain"] = base_domain + options["header_canon"] = header_canon + options["body_canon"] = body_canon + options["digest"] = digest + options["selector"] = selector + options["keyfile"] = key_file + options["identity"] = identity + + msys.validate.opendkim.sign(msg, vctx, options); +end + +function mod:core_post_final_validation(msg, accept, vctx) + -- do ARC sign + local sealer = {} + sealer.signing_domain = "sparkpost.com" + sealer.selector = "dkim-s1024" + sealer.keyfile = "path-to-keyfile" + sealer.headerlist = "From:Subject:Date:To:MIME-Version:Content-Type" + sealer.oversign_headerlist = "From:To:Subject" + + msys.validate.openarc.sign(msg, sealer) + + -- check sign/seal result + local ok = msg:context_get(msys.core.ECMESS_CTX_MESS, "arc_seal") + if ok == nil or ok == '' then + print("ARC seal failed. No ARC set add! Check paniclog for reasons.") + elseif ok == "skip" then + print("ARC seal skipped. No ARC set add: ARC chain failed before reaching me.") + else + print("ARC seal ok. ARC set added!") + end +end + +msys.registerModule("arc_sign", mod); +``` + +### Example 2: an intermediate MTA relay which does not modify the message other than ARC signing. + In such case, ARC verify and ARC sign can be done at the same time, in any hook in DATA phase + which does not block the main tasks. + +``` +require("msys.core"); +require("msys.validate.openarc"); +local mod = {}; + +function mod:core_final_validation(msg, accept, vctx) + -- do ARC signing (will trigger ARC verification implicitly) + local sealer = {} + sealer.signing_domain = "sparkpost.com" + sealer.selector = "dkim-s1024" + sealer.keyfile = "path-to-keyfile" + sealer.headerlist = "From:Subject:Date:To:MIME-Version:Content-Type" + sealer.oversign_headerlist = "From:To:Subject" + + msys.validate.openarc.sign(msg, sealer) + + -- check sign/seal result + local ok = msg:context_get(msys.core.ECMESS_CTX_MESS, "arc_seal") + if ok == nil or ok == '' then + print("ARC seal failed. No ARC set add! Check paniclog for reasons.") + elseif ok == "skip" then + print("ARC seal skipped. No ARC set add: ARC chain failed before reaching me.") + else + print("ARC seal ok. ARC set added!") + end +end + + +msys.registerModule("arc_sign", mod); +``` + From 293399de71ca3845dc66b864a4ee6394e6c0eceb Mon Sep 17 00:00:00 2001 From: Julie Zhao Date: Fri, 3 Jan 2025 15:24:33 -0500 Subject: [PATCH 11/13] minor format change --- .../momentum/4/lua/ref-msys-validate-openarc-sign.md | 2 +- content/momentum/4/modules/openarc.md | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/content/momentum/4/lua/ref-msys-validate-openarc-sign.md b/content/momentum/4/lua/ref-msys-validate-openarc-sign.md index aac0b4fc3..cd9f93db9 100644 --- a/content/momentum/4/lua/ref-msys-validate-openarc-sign.md +++ b/content/momentum/4/lua/ref-msys-validate-openarc-sign.md @@ -102,7 +102,7 @@ Since ARC sealing must not happen until all potential modification of a message The function would cause the `ec_message` context variable `arc_seal` to be set: -`ok`: ARC signing/sealing is done, and ARC set headers are added +`ok`: ARC signing/sealing is done, and ARC set headers are added. `skip`: ARC signing/sealing is skipped, because the ARC chain already fails before reaching the current MTA. diff --git a/content/momentum/4/modules/openarc.md b/content/momentum/4/modules/openarc.md index f764e050a..804e22abc 100644 --- a/content/momentum/4/modules/openarc.md +++ b/content/momentum/4/modules/openarc.md @@ -65,9 +65,11 @@ If there is absolutely no message modification, e.g. for a passthrough MTA which message other than ARC signing, calling `msys.validate.openarc.sign` alone can have some performance benefits: the message will be scanned once for both ARC verification and signing. -### Example 1: an intermediate MTA does ARC signing, which can potentially modify the email, e.g. - through DKIM signing, engagement tracking insertion and modification, etc. In such case, ARC verify - needs to happen first, and ARC sign later. +### Example 1: +The following policies define an intermediate MTA which does ARC signing and can potentially + modify the email, e.g. through DKIM signing, engagement tracking insertion and modification, etc. + In such case, ARC verify needs to happen first, followed by the logic to alter the message (e.g. + DKIM signing in the example), and then finally ARC sign at the last. ``` require("msys.core"); @@ -134,7 +136,8 @@ end msys.registerModule("arc_sign", mod); ``` -### Example 2: an intermediate MTA relay which does not modify the message other than ARC signing. +### Example 2: +The following policy defines an intermediate MTA relay which does not modify the message other than ARC signing. In such case, ARC verify and ARC sign can be done at the same time, in any hook in DATA phase which does not block the main tasks. From 2326e0783d23d2c6b086774e3454393e8b6aaeb4 Mon Sep 17 00:00:00 2001 From: Julie Zhao Date: Fri, 3 Jan 2025 15:48:06 -0500 Subject: [PATCH 12/13] minor: update sealer.headerlist in example --- content/momentum/4/modules/openarc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/momentum/4/modules/openarc.md b/content/momentum/4/modules/openarc.md index 804e22abc..c4a21f5fa 100644 --- a/content/momentum/4/modules/openarc.md +++ b/content/momentum/4/modules/openarc.md @@ -117,7 +117,7 @@ function mod:core_post_final_validation(msg, accept, vctx) sealer.signing_domain = "sparkpost.com" sealer.selector = "dkim-s1024" sealer.keyfile = "path-to-keyfile" - sealer.headerlist = "From:Subject:Date:To:MIME-Version:Content-Type" + sealer.headerlist = "From:Subject:Date:To:MIME-Version:Content-Type:DKIM-Signature" sealer.oversign_headerlist = "From:To:Subject" msys.validate.openarc.sign(msg, sealer) From 7e841afaafe70a427df733bc8bdf1a2595b2ac85 Mon Sep 17 00:00:00 2001 From: Julie Zhao Date: Thu, 9 Jan 2025 12:39:01 -0500 Subject: [PATCH 13/13] formatting --- content/momentum/4/modules/openarc.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/momentum/4/modules/openarc.md b/content/momentum/4/modules/openarc.md index c4a21f5fa..338ae4e50 100644 --- a/content/momentum/4/modules/openarc.md +++ b/content/momentum/4/modules/openarc.md @@ -127,7 +127,7 @@ function mod:core_post_final_validation(msg, accept, vctx) if ok == nil or ok == '' then print("ARC seal failed. No ARC set add! Check paniclog for reasons.") elseif ok == "skip" then - print("ARC seal skipped. No ARC set add: ARC chain failed before reaching me.") + print("ARC seal skipped. No ARC set add: ARC chain failed before reaching me.") else print("ARC seal ok. ARC set added!") end @@ -162,7 +162,7 @@ function mod:core_final_validation(msg, accept, vctx) if ok == nil or ok == '' then print("ARC seal failed. No ARC set add! Check paniclog for reasons.") elseif ok == "skip" then - print("ARC seal skipped. No ARC set add: ARC chain failed before reaching me.") + print("ARC seal skipped. No ARC set add: ARC chain failed before reaching me.") else print("ARC seal ok. ARC set added!") end