diff --git a/src/App/Type/DMARC.purs b/src/App/Type/DMARC.purs index 33535c5..7850da2 100644 --- a/src/App/Type/DMARC.purs +++ b/src/App/Type/DMARC.purs @@ -4,6 +4,7 @@ import Prelude import Data.Generic.Rep (class Generic) import Data.Show.Generic (genericShow) +import Data.Tuple (Tuple(..)) import App.Type.GenericSerialization (generic_serialization) import Data.Maybe (Maybe(..)) @@ -11,44 +12,67 @@ import Data.Codec.Argonaut (JsonCodec) import Data.Codec.Argonaut as CA import Data.Codec.Argonaut.Record as CAR +-- | MailTo is a simple alias for String. This is an over-simplification that may change in the future. +type MailTo = String + type DMARC = { -- | adkim= Optional. - -- | Consistency policy for DKIM. Either strict (dkim signature domain = "From:" field) or relaxed. + -- | Consistency policy for DKIM. + -- | Either strict (dkim signature domain = "From:" field) or relaxed (both in the same Organizational Domain). adkim :: Maybe ConsistencyPolicy + -- | aspf= Optional. - -- | Consistency policy for SPF. Either strict (dkim signature domain = "From:" field) or relaxed. + -- | Consistency policy for SPF. + -- | Either strict ("MailFrom:" same as "From:") or relaxed (both in the same Organizational Domain). , aspf :: Maybe ConsistencyPolicy - -- | v= "DMARC1", entirely optional (for now, even ignored). + + -- | v= Required. Default is "DMARC1", so the implementation doesn't actually require it. , v :: Maybe Version - -- | pct= Percentage of messages to filter [0...100], 100 by default. - , pct :: Int - -- | p= Requested Mail Receiver policy (None, Quarantine, Reject). + + -- | pct= Optional. Percentage of messages to filter [0...100], 100 by default. + , pct :: Maybe Int + + -- | p= Required. Requested Mail Receiver policy (None, Quarantine, Reject). , p :: Policy - -- | sp= Requested Mail Receiver policy for all subdomains. - , sp :: Policy - -- | ruf= Addresses to which message-specific failure information is to be reported. - , ruf :: MailTo - -- | fo= When to send a report (on DKIM or SPF error? Any? Both?). + + -- | sp= Optional. Requested Mail Receiver policy for all subdomains. + , sp :: Maybe Policy + + -- | fo= Optional. When to send a report (on DKIM or SPF error? Any? Both?). , fo :: Maybe ReportOccasion - -- | rua= Where to send the aggregated reports. A size limit can be provided (see `rua_maxlen`). - , rua :: MailTo - -- | Optional. !XXm Max size of the report (in megabytes). - , rua_maxlen :: Maybe Int - -- | rf= Optional. Report format, AFRF by default. - , rf :: Maybe Format - -- | ri= Optional. Interval requested between aggregate reports. By default 86400. + + -- | rua= Optional. Addresses to which aggregate feedback is to be sent. + -- | A size limit can be provided (in KB). + , rua :: Maybe (Array (Tuple MailTo Int)) + + -- | ruf= Optional. Addresses to which message-specific failure information is to be reported. + , ruf :: Array MailTo + + -- | rf= Optional. List of accepted report format, AFRF by default. + , rf :: Maybe (Array Format) + + -- | ri= Optional. Interval requested between aggregate reports. Default is 86400. , ri :: Maybe Int } -data ReportOccasion = Both | DKIMonly | SPFonly | AnyOccasion +data ReportOccasion + -- | Both DKIM and SPF should be in error to have a report. + = Both + -- | DKIM should be erroneous to produce a report. + | DKIMonly + -- | SPF should be erroneous to produce a report. + | SPFonly + -- | Produce a report whether SPF or DKIM is erroneous. + | Any data ConsistencyPolicy -- | s = strict. -- | - -- | For DKIM: DKIM signature and "From:" field should have the exact same domain. + -- | For DKIM: DKIM signature should first be verified. + -- | Then, the "From:" field should be the exact same domain as the DKIM signature domain. -- | - -- | For SPF: First, SPF should produce a passing result. Then, the "From:" and the "MailFrom:" fields are checked. + -- | For SPF: first, SPF should produce a passing result. Then, the "From:" and the "MailFrom:" fields are checked. -- | In strict mode, Both "MailFrom:" and "From:" fields should have the same value. -- | -- | From RFC7489: For example, if a message passes an SPF check with an @@ -57,17 +81,30 @@ data ConsistencyPolicy -- | the Authenticated RFC5321.MailFrom domain identifier and the -- | RFC5322.From domain are considered to be "in alignment" in relaxed -- | mode, but not in strict mode. + -- | See https://publicsuffix.org/ for a list of organizational domains. = Strict -- | r = relaxed, default. -- | - -- | For DKIM: "From:" field can be in the same domain of the domain of the DKIM signature. + -- | For DKIM: DKIM signature should first be verified. + -- | Then, the "From:" field should have the same domain as the DKIM signature domain or be in the same + -- | Organizational Domain. -- | Example: "From:" is example@foo.example.org, DKIM signature can be d=example.org or d=bar.example.org. -- | - -- | For SPF: + -- | For SPF: as for "strict" policy, SPF should first produce a passing result. + -- | Then, the "From:" and the "MailFrom:" fields should be checked. + -- | In relaxed mode, they can be different, but in the same Organizational Domain. + -- | See https://publicsuffix.org/ for a list of organizational domains. | Relaxed -data Format = AFRF -- Authentication Failure Reporting Format -data Version = DMARC1 +data Format + -- | Authentication Failure Reporting Format, see RFC6591. Currently the only format referenced in RFC7489. + = AFRF + +data Version + -- | Version of DMARC only accepts DMARC1 currently. + -- | So, for dnsmanager, this field is just ignored for now. + = DMARC1 + data Policy -- | "None" means to basically just accept the mail. = None @@ -75,5 +112,3 @@ data Policy | Quarantine -- | "Reject" means to not accept any failure of DKIM or SPF. | Reject - -type MailTo = String