lib/spf/model.rb in spf-0.0.1 vs lib/spf/model.rb in spf-0.0.2
- old
+ new
@@ -83,10 +83,19 @@
:: (?: #{HEXWORD_PATTERN} : ){0,5} #{TWO_HEXWORDS_OR_IPV4_ADDRESS_PATTERN} |
# :: | -
::
"
+ attr_reader :ip_address, :ip_network, :ipv4_prefix_length, :ipv6_prefix_length
+
+ def initialize
+ @ip_address = nil
+ @ip_network = nil
+ @ipv4_prefix_length = nil
+ @ipv6_prefix_length = nil
+ end
+
def self.new_from_string(text, options = {})
#term = SPF::Term.new(options, {:text => text})
options[:text] = text
term = self.new(options)
term.parse
@@ -208,11 +217,11 @@
@text = options[:text]
if not self.instance_variable_defined?(:@parse_text)
@parse_text = @text.dup
end
if self.instance_variable_defined?(:@domain_spec) and
- not @domain_spec.is_a?(SPF::MacroString)
+ not SPF::MacroString === @domain_spec
@domain_spec = SPF::MacroString.new({:text => @domain_spec})
end
end
def parse
@@ -349,11 +358,11 @@
params += '//' + @ipv6_prefix_length
end
return params
end
- def match(server, request)
+ def match(server, request, want_result = true)
server.count_dns_interactive_term(request)
return self.match_in_domain(server, request)
end
end
@@ -364,11 +373,11 @@
def parse_params
# No parameters.
end
- def match(server, request)
+ def match(server, request, want_result = true)
return true
end
end
@@ -382,11 +391,11 @@
def params
return @domain_spec ? ':' + @domain_spec : nill
end
- def match(server, request)
+ def match(server, request, want_result = true)
server.count_dns_interactive_term(request)
domain = self.domain(server, request)
packet = server.dns_lookup(domain, 'A')
rrs = (packet.answer or server.count_void_dns_lookup(request))
@@ -412,12 +421,12 @@
result += "/#{@ip_network.masklen}"
end
return result
end
- def match(server, request)
- ip_network_v6 = @ip_network.is_a?(IP::V4) ?
+ def match(server, request, want_result = true)
+ ip_network_v6 = IP::V4 === @ip_network ?
SPF::Util.ipv4_address_to_ipv6(@ip_network) :
@ip_network
return ip_network_v6.contains?(request.ip_address_v6)
end
@@ -436,11 +445,11 @@
params += '/' + @ip_network.masklen if
@ip_network.masklen != DEFAULT_IPV6_PREFIX_LENGTH
return params
end
- def match(server, request)
+ def match(server, request, want_result = true)
return @ip_network.contains?(request.ip_address_v6)
end
end
@@ -454,11 +463,12 @@
def params
return @domain_spec ? ':' + @domain_spec : nil
end
- def match(server, request)
+ def match(server, request, want_result = true)
+
server.count_dns_interactive_term(request)
# Create sub-request with mutated authority domain:
authority_domain = self.domain(server, request)
sub_request = request.new_sub_request({:authority_domain => authority_domain})
@@ -466,21 +476,22 @@
# Process sub-request:
result = server.process(sub_request)
# Translate result of sub-request (RFC 4408, 5.9):
- return true if
- result.is_a?(SPF::Result::Pass)
+ return false unless want_result
+ return true if SPF::Result::Pass === result
+
return false if
- result.is_a?(SPF::Result::Fail) or
- result.is_a?(SPF::Result::SoftFail) or
- result.is_a?(SPF::Result::Neutral)
+ SPF::Result::Fail === result or
+ SPF::Result::SoftFail === result or
+ SPF::Result::Neutral === result or
server.throw_result('permerror', request,
"Include domain '#{authority_domain}' has no applicable sender policy") if
- result.is_a?(SPF::Result::None)
+ SPF::Result::None === result
# Propagate any other results (including {Perm,Temp}Error) as-is:
raise result
end
end
@@ -506,11 +517,11 @@
params += '//' + @ipv6_prefix_length
end
return params
end
- def match(server, request)
+ def match(server, request, want_result = true)
server.count_dns_interactive_term(request)
target_domain = self.domain(server, request)
mx_packet = server.dns_lookup(target_domain, 'MX')
@@ -547,11 +558,11 @@
def params
return @domain_spec ? ':' + @domain_spec : nil
end
- def match(server, request)
+ def match(server, request, want_result = true)
return SPF::Util.valid_domain_for_ip_address(
server, request, request.ip_address, self.domain(server, request)) ?
true : false
end
end
@@ -564,11 +575,11 @@
@text = options[:text]
@domain_spec = options[:domain_spec]
@parse_text = @text.dup unless @parse_text
- if @domain_spec and not @domain_spec.is_a?(SPF::MacroString)
+ if @domain_spec and not SPF::MacroString === @domain_spec
@domain_spec = SPF::MacroString.new({:text => @domain_spec})
end
end
def parse
@@ -682,21 +693,21 @@
def process(server, request, result)
server.count_dns_interactive_term(request)
# Only perform redirection if no mechanism matched (RFC 4408, 6.1/1):
- return unless result.is_a?(SPF::Result::NeutralByDefault)
+ return unless SPF::Result::NeutralByDefault === result
# Create sub-request with mutated authorithy domain:
authority_domain = @domain_spec.new({:server => server, :request => request})
sub_request = request.new_sub_request({:authority_domain => authority_domain})
# Process sub-request:
result = server.process(sub_request)
# Translate result of sub-request (RFC 4408, 6.1/4):
- if result.is_a?(SPF::Result::None)
+ if SPF::Result::None === result
server.throw_result(:permerror, request,
"Redirect domain '#{authority_domain}' has no applicable sender policy")
end
# Propagate any other results as-is:
@@ -787,17 +798,17 @@
mod_name = $2.downcase
mod_class = MOD_CLASSES[mod_name]
if mod_class
# Known modifier.
mod = mod_class.new_from_string(mod_text)
- if mod.is_a?(SPF::GlobalMod)
+ if SPF::GlobalMod === mod
# Global modifier.
unless @global_mods[mod_name]
raise SPF::DuplicateGlobalMod.new("Duplicate global modifier '#{mod_name}' encountered")
end
@global_mods[mod_name] = mod
- elsif mod.is_a?(SPF::PositionalMod)
+ elsif SPF::PositionalMod === mod
# Positional modifier, queue normally:
@terms << mod
end
end
else
@@ -820,30 +831,30 @@
def eval(server, request)
raise SPF::OptionRequiredError.new('SPF server object required for record evaluation') unless server
raise SPF::OptionRequiredError.new('Request object required for record evaluation') unless request
begin
@terms.each do |term|
- if term.is_a?(SPF::Mech)
+ if SPF::Mech === term
+ #if term.is_a?(SPF::Mech)
# Term is a mechanism.
mech = term
- if mech.match(server, request)
+ if mech.match(server, request, request.ip_address != nil)
result_name = RESULTS_BY_QUALIFIER[mech.qualifier]
result_class = server.result_class(result_name)
result = result_class.new([server, request, "Mechanism '#{term}' matched"])
mech.explain(server, request, result)
raise result
end
- elsif term.is_a?(SPF::PositionalMod)
+ elsif SPF::PositionalMod === term
# Term is a positional modifier.
mod = term
mod.process(server, request)
- elsif term.is_a?(SPF::UnknownMod)
+ elsif SPF::UnknownMod === term
# Term is an unknown modifier. Ignore it (RFC 4408, 6/3).
else
# Invalid term object encountered:
- raise SPF::UnexpectedTermObjectError.new(
- "Unexpected term object '#{term}' encountered.")
+ raise SPF::UnexpectedTermObjectError.new("Unexpected term object '#{term}' encountered.")
end
end
rescue SPF::Result => result
# Process global modifiers in ascending order of precedence:
@global_mods.each do |global_mod|
@@ -875,9 +886,13 @@
def scopes
[:helo, :mfrom]
end
def version_tag
+ 'v=spf1'
+ end
+
+ def self.version_tag
'v=spf1'
end
def version_tag_pattern
" v=spf(1) (?= \\x20+ | $ ) "