aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Joe Banks <[email protected]>2025-05-29 00:43:50 +0100
committerGravatar Joe Banks <[email protected]>2025-05-29 00:43:50 +0100
commit8f5a18061f68b30af5f3e71f3c9eb9b0202b4f2d (patch)
tree1d1c0c4ad13266ce35a678cd59f32a5bcf5180bf
parentAdd dmarc_parser and dmarc_lexer generated files to gitignore (diff)
DMARC get_dmarc_policy/1 does everything now
-rw-r--r--lib/dmarc.ex60
1 files changed, 27 insertions, 33 deletions
diff --git a/lib/dmarc.ex b/lib/dmarc.ex
index 1be5da3..43c1fa4 100644
--- a/lib/dmarc.ex
+++ b/lib/dmarc.ex
@@ -1,40 +1,34 @@
defmodule Lithium.DMARC do
require Logger
- def get_dmarc_record(domain) do
- with od <- Lithium.Util.PublicSuffix.get_domain(domain),
- {:ok, records} <- Lithium.DNS.fetch_txt("_dmarc." <> od) do
-
- filtered =
- records
- |> Enum.map(&String.trim/1)
- |> Enum.filter(fn found_record ->
- # As per Section 7.1, DMARC report authorisations also use a format of "v=DMARC1"
- # We should check when we find a tag that it is not *just* a version record.
-
- # It would technically be invalid to serve this DMARC report authorisation from
- # _dmarc.domain.com, however from testing some people do peculiar deployments
- # using wildcards and it ends up showing there.
-
- # For now, we should probably be lenient and just ignore the report authorisation
- # instead of tossing the entire DMARC validation process.
- trimmed =
- found_record
- |> String.replace(" ", "")
-
- String.starts_with?(trimmed, "v=DMARC1;") and trimmed != "v=DMARC1;"
- end)
-
- case filtered do
- [] ->
- {:error, :nxdomain}
-
- [record] ->
- {:ok, record}
+ defp select_record(records) do
+ filtered =
+ records
+ |> Enum.map(&String.trim/1)
+ |> Enum.filter(fn found_record ->
+ # As per Section 7.1, DMARC report authorisations also use a format of "v=DMARC1"
+ # We should check when we find a tag that it is not *just* a version record.
+ trimmed = String.replace(found_record, " ", "")
+ String.starts_with?(trimmed, "v=DMARC1;") and trimmed != "v=DMARC1;"
+ end)
+
+ case filtered do
+ [] ->
+ {:error, :nxdomain}
+ [record] ->
+ {:ok, record}
+ _ ->
+ {:error, :multiple_records}
+ end
+ end
- _ ->
- {:error, :multiple_records}
- end
+ def get_dmarc_policy(domain) do
+ with od <- Lithium.Util.PublicSuffix.get_domain(domain),
+ {:ok, records} <- Lithium.DNS.fetch_txt("_dmarc." <> od),
+ {:ok, record } <- select_record(records),
+ {:ok, policy} <- Lithium.DMARC.Parser.parse_policy(record)
+ do
+ {:ok, policy}
else
error ->
error