Module: MtaSts

Defined in:
lib/mta_sts.rb,
lib/mta_sts/cli.rb,
lib/mta_sts/policy.rb,
lib/mta_sts/report.rb,
lib/mta_sts/result.rb,
lib/mta_sts/fetcher.rb,
lib/mta_sts/version.rb,
lib/mta_sts/resolver.rb,
lib/mta_sts/report/result.rb

Defined Under Namespace

Classes: Cli, Fetcher, Policy, Report, Resolver, Result

Constant Summary collapse

DISCOVERY_PREFIX =
"_mta-sts."
POLICY_HOST_PREFIX =
"mta-sts."
REPORTING_PREFIX =

RFC 8460 §3

"_smtp._tls."
STS_RECORD =

RFC 8461 §3.1 ABNF: sts-version = %s"v=STSv1", then sts-field-delim

/\Av=STSv1;/
FIELD_DELIM =
";"
ID_FIELD =
/\Aid=(.*)\z/
STS_ID =

RFC 8461 §3.1 ABNF: sts-id = 1*32(ALPHA / DIGIT)

/\A[a-zA-Z0-9]{1,32}\z/
VERSION =
"0.1.1"

Class Method Summary collapse

Class Method Details

.lookup(domain, known:, resolver: Resolver.new, fetcher: Fetcher.new, now: Time.now) ⇒ Object

known: is required so omitting it is a decision, not an accident (§5.1).



24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/mta_sts.rb', line 24

def lookup(domain, known:, resolver: Resolver.new, fetcher: Fetcher.new, now: Time.now)
  domain = Policy.normalize(recipient_domain(domain))
  held = usable(known, domain, now)
  id = discover(domain, resolver)

  case
  when id == :unreachable    then unreachable(domain, held)
  when id == :absent         then absent(domain, held)
  when held && held.id == id then renewed(domain, held, now)
  else                            fetched(domain, id, held, fetcher, now)
  end
end

.reporting(domain, resolver: Resolver.new) ⇒ Object

RFC 8460 §3



38
39
40
41
42
43
44
45
46
# File 'lib/mta_sts.rb', line 38

def reporting(domain, resolver: Resolver.new)
  domain = Policy.normalize(recipient_domain(domain))

  case record = sole_record("#{REPORTING_PREFIX}#{domain}", matching: Report::REPORT_RECORD, resolver: resolver)
  when :unreachable then unanswered(domain)
  when :absent      then unpublished(domain)
  else                   reported(domain, record)
  end
end