Class: MailAuth::Arc::Set

Inherits:
Object
  • Object
show all
Defined in:
lib/mailauth/arc/set.rb

Overview

The three header fields sharing one instance value (RFC 8617 §4.2). Each is held as the list of fields claiming this instance, so a set that carries two of anything can say so rather than quietly keeping one.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(instance) ⇒ Set

Returns a new instance of Set.



9
10
11
12
# File 'lib/mailauth/arc/set.rb', line 9

def initialize(instance)
  @instance = instance
  @fields = { authentication_results: [], message_signature: [], seal: [] }
end

Instance Attribute Details

#instanceObject (readonly)

Returns the value of attribute instance.



7
8
9
# File 'lib/mailauth/arc/set.rb', line 7

def instance
  @instance
end

Instance Method Details

#add(kind, field) ⇒ Object



14
15
16
# File 'lib/mailauth/arc/set.rb', line 14

def add(kind, field)
  @fields.fetch(kind) << field
end

#authentication_resultsObject



28
29
30
# File 'lib/mailauth/arc/set.rb', line 28

def authentication_results
  @fields[:authentication_results].first
end

#authentication_results_payloadObject

The payload an Authentication-Results header would carry, with the instance tag that prefixes it here (§4.1.1) taken off.



60
61
62
# File 'lib/mailauth/arc/set.rb', line 60

def authentication_results_payload
  Arc.value_of(authentication_results).to_s.sub(INSTANCE_PREFIX, "").strip
end

#chain_statusObject

The status this hop stamped, which §5.2 step 3.3 holds to "none" at instance 1 and "pass" above it.



42
43
44
# File 'lib/mailauth/arc/set.rb', line 42

def chain_status
  seal_tags.to_h["cv"].to_s.downcase
end

#claimedObject

Best effort, and never load-bearing: the chain's validity is a question about signatures, so an unreadable assertion must not fail it. A name carrying a dot is one of RFC 8601's properties (smtp.mailfrom), not a method, and says nothing about a verdict.



68
69
70
71
# File 'lib/mailauth/arc/set.rb', line 68

def claimed
  authentication_results_payload.scan(/(?<![\w.-])([a-z][a-z0-9-]*)[ \t]*=[ \t]*([a-z]+)/i).
    each_with_object({}) { |(method, result), claims| claims[method.downcase] ||= result.downcase }
end

#complete?Boolean

Returns:

  • (Boolean)


18
19
20
# File 'lib/mailauth/arc/set.rb', line 18

def complete?
  @fields.each_value.all?(&:one?)
end

#message_signatureObject



32
33
34
# File 'lib/mailauth/arc/set.rb', line 32

def message_signature
  @fields[:message_signature].first
end

#message_signature_tagsObject



52
53
54
55
56
# File 'lib/mailauth/arc/set.rb', line 52

def message_signature_tags
  return @message_signature_tags if defined?(@message_signature_tags)

  @message_signature_tags = Arc.tags_in(message_signature)
end

#readable?Boolean

A tag list that doesn't parse leaves nothing to verify against, and no reading of the rest can rescue it (RFC 6376 §3.2).

Returns:

  • (Boolean)


24
25
26
# File 'lib/mailauth/arc/set.rb', line 24

def readable?
  !seal_tags.nil? && !message_signature_tags.nil?
end

#sealObject



36
37
38
# File 'lib/mailauth/arc/set.rb', line 36

def seal
  @fields[:seal].first
end

#seal_tagsObject



46
47
48
49
50
# File 'lib/mailauth/arc/set.rb', line 46

def seal_tags
  return @seal_tags if defined?(@seal_tags)

  @seal_tags = Arc.tags_in(seal)
end