SPF: new validations of mechanisms. TODO: CIDR. Domain specs maybe someday.

This commit is contained in:
Philippe Pittoli 2024-03-07 03:46:33 +01:00
parent bf5efccca7
commit 74f5718f99

View File

@ -199,21 +199,44 @@ or_nothing p = do v <- G.tryMaybe p
_, Just _ -> pure "" _, Just _ -> pure ""
Nothing, Nothing -> p -- at least give the right error results Nothing, Nothing -> p -- at least give the right error results
-- | `validate_SPF_mechanism` validates the different values for each mechanism.
-- | A and MX can both either doesn't have a value or a domain name.
-- | EXISTS requires a domain name.
-- |
-- | **What differs from RFC7208**:
-- | Some features of the mechanisms described in RFC7208 are lacking.
-- | For instance, INCLUDE, A, MX, PTR and EXISTS accept domain *specs* not simply domain *names*.
-- | Also, some of them should accept a CIDR, which currently isn't a thing.
-- |
-- | TODO: I don't intend to implement the full RFC7208, but accepting CIDR can be done.
validate_SPF_mechanism :: Mechanism -> V (Array Error) Mechanism validate_SPF_mechanism :: Mechanism -> V (Array Error) Mechanism
validate_SPF_mechanism m = case m.t of validate_SPF_mechanism m = case m.t of
RR.A -> ado -- RFC: `a = "a" [ ":" domain-spec ] [ dual-cidr-length ]`
name <- parse (or_nothing DomainParser.sub_eof) m.v VESPFMechanismName RR.A -> test (or_nothing DomainParser.sub_eof) VESPFMechanismName
-- RFC: `mx = "mx" [ ":" domain-spec ] [ dual-cidr-length ]`
RR.MX -> test (or_nothing DomainParser.sub_eof) VESPFMechanismName
-- RFC: `exists = "exists" ":" domain-spec`
RR.EXISTS -> test DomainParser.sub_eof VESPFMechanismName
-- RFC: `ptr = "ptr" [ ":" domain-spec ]`
RR.PTR -> test (or_nothing DomainParser.sub_eof) VESPFMechanismName
-- RFC: `ip4 = "ip4" ":" ip4-network [ ip4-cidr-length ]`
RR.IP4 -> test (IPAddress.ipv4_range <|> IPAddress.ipv4) VESPFMechanismIPv4
-- RFC: `ip6 = "ip6" ":" ip6-network [ ip6-cidr-length ]`
RR.IP6 -> test (IPAddress.ipv6_range <|> IPAddress.ipv6) VESPFMechanismIPv6
-- RFC: `include = "include" ":" domain-spec`
RR.INCLUDE -> test DomainParser.sub_eof VESPFMechanismName
where
test :: forall e. G.Parser e String -> ((G.Error e) -> Error) -> V (Array Error) Mechanism
test p e = ado
name <- parse p m.v e
in first m name -- name is discarded in first m name -- name is discarded
RR.MX -> ado
name <- parse (or_nothing DomainParser.sub_eof) m.v VESPFMechanismName
in first m name -- name is discarded
RR.IP4 -> ado
name <- parse (IPAddress.ipv4_range <|> IPAddress.ipv4) m.v VESPFMechanismIPv4
in first m name -- name is discarded
RR.IP6 -> ado
name <- parse (IPAddress.ipv6_range <|> IPAddress.ipv6) m.v VESPFMechanismIPv6
in first m name -- name is discarded
_ -> pure m
validate_SPF_modifier :: Modifier -> V (Array Error) Modifier validate_SPF_modifier :: Modifier -> V (Array Error) Modifier
validate_SPF_modifier m = case m.t of validate_SPF_modifier m = case m.t of