diff --git a/src/App/Page/Zone.purs b/src/App/Page/Zone.purs index 47d0512..b03389d 100644 --- a/src/App/Page/Zone.purs +++ b/src/App/Page/Zone.purs @@ -540,25 +540,33 @@ render state state._currentRR.name display_domain_side , Bulma.box_input "ttlDMARC" "TTL" "600" (updateForm Field_TTL) (show state._currentRR.ttl) + , Bulma.hr + , Bulma.div_content [Bulma.explanation Explanations.dmarc_policy] , Bulma.selection_field "idDMARCPolicy" "Policy" DMARC_policy (map show DMARC.policies) (show state.dmarc.p) + , Bulma.div_content [Bulma.explanation Explanations.dmarc_sp_policy] , Bulma.selection_field "idDMARCPolicy_sp" "Policy for subdomains" DMARC_sp_policy (["do not provide policy advice"] <> map show DMARC.policies) (maybe "-" show state.dmarc.sp) + , Bulma.hr + , Bulma.div_content [Bulma.explanation Explanations.dmarc_adkim] , Bulma.selection_field "idDMARCadkim" "Consistency Policy for DKIM" DMARC_adkim DMARC.consistency_policies_txt_dkim (maybe "-" show state.dmarc.adkim) + , Bulma.div_content [Bulma.explanation Explanations.dmarc_aspf] , Bulma.selection_field "idDMARCaspf" "Consistency Policy for SPF" DMARC_aspf DMARC.consistency_policies_txt_spf (maybe "-" show state.dmarc.aspf) + , Bulma.hr , Bulma.box_input "idDMARCpct" "% of dropped emails" "100" DMARC_pct (maybe "100" show state.dmarc.pct) + , Bulma.hr , Bulma.selection_field "idDMARCfo" "When to send a report" DMARC_fo DMARC.report_occasions_txt (maybe "-" show state.dmarc.fo) , Bulma.hr - , maybe (Bulma.p "no rua") (display_dmarc_mail_addresses DMARC_remove_rua) current_ruas - , maybe (Bulma.p "no ruf") (display_dmarc_mail_addresses DMARC_remove_ruf) current_rufs - , Bulma.box_input "idDMARCmail" "Address to contact" "" DMARC_mail state.dmarc_mail - , Bulma.box_input "idDMARCmaillimit" "Report size limit (in KB)" "" DMARC_mail_limit (maybe "0" show state.dmarc_mail_limit) + , maybe (Bulma.p "There is no address to send aggragated reports to.") (display_dmarc_mail_addresses DMARC_remove_rua) current_ruas + , maybe (Bulma.p "There is no address to send detailed reports to.") (display_dmarc_mail_addresses DMARC_remove_ruf) current_rufs + , Bulma.box_input "idDMARCmail" "Address to contact" "admin@example.com" DMARC_mail state.dmarc_mail + , Bulma.box_input "idDMARCmaillimit" "Report size limit (in KB)" "2000" DMARC_mail_limit (maybe "0" show state.dmarc_mail_limit) , Bulma.level [ Bulma.btn "New address for aggregated report" DMARC_rua_Add , Bulma.btn "New address for specific report" DMARC_ruf_Add - ] + ] [] ] current_ruas = case state._currentRR.dmarc of diff --git a/src/App/Text/Explanations.purs b/src/App/Text/Explanations.purs index bc0e349..415a253 100644 --- a/src/App/Text/Explanations.purs +++ b/src/App/Text/Explanations.purs @@ -1,5 +1,6 @@ module App.Text.Explanations where import Halogen.HTML as HH +import Halogen.HTML.Properties as HP import Bulma as Bulma expl' :: forall w i. String -> HH.HTML w i @@ -166,6 +167,66 @@ dmarc_introduction = """ ] +dmarc_policy :: forall w i. Array (HH.HTML w i) +dmarc_policy = + [ Bulma.p """ + DMARC record allows to tell receivers what to do with a non-conforming message; + a message that wasn't properly secured with SPF and DKIM. + """ + , Bulma.p """ + This message can either be accepted ("None") or rejected, or even quarantined, meaning to be considered as suspicious. + This can take different forms, such as being flagged, marked as spam or have a high "spam score", it's up to the receiver. + """ + ] + +dmarc_sp_policy :: forall w i. Array (HH.HTML w i) +dmarc_sp_policy = + [ Bulma.p """ + Same as the previous entry, but for sub-domains. + """ + ] + +dmarc_adkim :: forall w i. Array (HH.HTML w i) +dmarc_adkim = + [ Bulma.p """ + Consistency policy for DKIM. Tell what should be considered acceptable. + """ + , Bulma.p """ + This is about the relation between the email "From:" field and the domain field of the DKIM signature ("d:"). + """ + , Bulma.p """ + The policy can be either strict (both should be identical) or relaxed (both in the same Organizational Domain). + """ + ] + +dmarc_aspf :: forall w i. Array (HH.HTML w i) +dmarc_aspf = + [ Bulma.p """ + Consistency policy for SPF. Tell what should be considered acceptable. + """ + , Bulma.p """ + First, SPF should produce a passing result. + Then, the "From:" and the "MailFrom:" fields of the received email are checked. + """ + , Bulma.p """ + In strict mode, both fields should be identical. + In relaxed mode, they can be different, but in the same Organizational Domain. + """ + , Bulma.p """ + From RFC7489: For example, if a message passes an SPF check with an + RFC5321.MailFrom domain of "cbg.bounces.example.com", and the address + portion of the RFC5322.From field contains "payments@example.com", + 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. + """ + , HH.p_ + [ HH.text "See " + , HH.a [HP.href "https://publicsuffix.org/"] [ HH.text "publicsuffix.org" ] + , HH.text " for a list of organizational domains." + ] + ] + dkim_default_algorithms :: forall w i. Array (HH.HTML w i) dkim_default_algorithms = diff --git a/src/App/Type/DMARC.purs b/src/App/Type/DMARC.purs index ed2f7ed..6c7b482 100644 --- a/src/App/Type/DMARC.purs +++ b/src/App/Type/DMARC.purs @@ -168,15 +168,15 @@ consistency_policies = [Strict, Relaxed] consistency_policies_txt_spf :: Array String consistency_policies_txt_spf = [ "Do not provide policy advice" - , "Strict: \"From:\" and SPF domain must be identical" - , "Relaxed: \"From:\" and SPF domain must be in the same organizational domain" + , "Strict: identical domains" + , "Relaxed: same organizational domain" ] consistency_policies_txt_dkim :: Array String consistency_policies_txt_dkim = [ "Do not provide policy advice" - , "Strict: \"From:\" and DKIM domain (\"d:\") must be identical" - , "Relaxed: \"From:\" and DKIM domain (\"d:\") must be in the same organizational domain" + , "Strict: same domain" + , "Relaxed: same organizational domain" ]