class SPF::Mech

Constants

DEFAULT_QUALIFIER
EXPLANATION_TEMPLATES_BY_RESULT_CODE
NAME_PATTERN
QUALIFIER_PATTERN

Public Class Methods

new(options) click to toggle source
Calls superclass method SPF::Term::new
# File lib/spf/model.rb, line 253
def initialize(options)
  super(options)

  @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 SPF::MacroString === @domain_spec
    @domain_spec = SPF::MacroString.new({:text => @domain_spec})
  end
end

Public Instance Methods

default_ipv4_prefix_length() click to toggle source
# File lib/spf/model.rb, line 240
def default_ipv4_prefix_length; 32;   end
default_ipv6_prefix_length() click to toggle source
# File lib/spf/model.rb, line 241
def default_ipv6_prefix_length; 128;  end
explain(server, request, result) click to toggle source
# File lib/spf/model.rb, line 367
def explain(server, request, result)
  explanation_template = self.explanation_template(server, request, result)
  return unless explanation_template
  begin
    explanation = SPF::MacroString.new({
      :text           => explanation_template,
      :server         => server,
      :request        => request,
      :is_explanation => true
    })
    request.state(:local_explanation, explanation)
  rescue SPF::Error
  rescue SPF::Result
  end
end
explanation_template(server, request, result) click to toggle source
# File lib/spf/model.rb, line 383
def explanation_template(server, request, result)
  return EXPLANATION_TEMPLATES_BY_RESULT_CODE[result.code]
end
match_in_domain(server, request, domain) click to toggle source
# File lib/spf/model.rb, line 328
def match_in_domain(server, request, domain)
  domain = self.domain(server, request) unless domain

  ipv4_prefix_length = @ipv4_prefix_length || self.default_ipv4_prefix_length
  ipv6_prefix_length = @ipv6_prefix_length || self.default_ipv6_prefix_length

  begin
    rrs_a = server.dns_lookup(domain.to_s, 'A') || []
  rescue SPF::DNSError => e
    @errors << e
    return false
  end
  begin
    rrs_aaaa = server.dns_lookup(domain.to_s, 'AAAA') || []
  rescue SPF::DNSError => e
    @errors << e
    return false
  end

  rrs = rrs_a + rrs_aaaa
  server.count_void_dns_lookup(request) if rrs.empty?

  rrs.each do |rr|
    if Resolv::DNS::Resource::IN::A === rr
      network = IP.new("#{rr.address}/#{ipv4_prefix_length}")
      @ip_netblocks << network
      return true if network.contains?(request.ip_address)
    elsif Resolv::DNS::Resource::IN::AAAA === rr
      network = IP.new("#{rr.address}/#{ipv6_prefix_length}")
      @ip_netblocks << network
      return true if network.contains?(request.ip_address_v6)
    else
      # Unexpected RR type.
      # TODO: Generate debug info or ignore silently.
    end
  end
  return false
end
params() click to toggle source
# File lib/spf/model.rb, line 276
def params; nil; end
parse() click to toggle source
# File lib/spf/model.rb, line 266
def parse
  if not @parse_text
    raise SPF::NothingToParseError.new('Nothing to parse for mechanism')
  end
  parse_qualifier
  parse_name      if @errors.empty?
  parse_params    if @errors.empty?
  parse_end       if @errors.empty?
end
parse_end() click to toggle source
# File lib/spf/model.rb, line 304
def parse_end
  unless @parse_text == ''
    error(SPF::JunkInTermError.new("Junk encountered in mechanism '#{@text}'", @text, @parse_text))
  end
  @parse_text = nil
end
parse_name() click to toggle source
# File lib/spf/model.rb, line 287
def parse_name
  if @parse_text.sub!(/^ (#{NAME_PATTERN}) (?: : (?=.) )? /x, '')
    @name = $1
  else
    error(SPF::InvalidMechError.new("Unexpected mechanism encountered in '#{@text}'"))
  end
end
parse_params(required = true) click to toggle source
# File lib/spf/model.rb, line 295
def parse_params(required = true)
  @raw_params = @parse_text.dup
  # Parse generic string of parameters text (should be overridden in sub-classes):
  if @parse_text.sub!(/^(.*)/, '')
    @params_text = $1
    @raw_params  = @params_text.dup
  end
end
parse_qualifier() click to toggle source
# File lib/spf/model.rb, line 278
def parse_qualifier
  if @parse_text.sub!(/(#{QUALIFIER_PATTERN})?/x, '')
    @qualifier = $1 or DEFAULT_QUALIFIER
  else
    error(SPF::InvalidMechQualifierError.new(
        "Invalid qualifier encountered in '#{@text}'"))
  end
end
qualifier() click to toggle source
# File lib/spf/model.rb, line 311
def qualifier
  # Read-only!
  return @qualifier if self.instance_variable_defined?(:@qualifier) and @qualifier
  return DEFAULT_QUALIFIER
end
to_s() click to toggle source
# File lib/spf/model.rb, line 317
def to_s
  @params = nil unless self.instance_variable_defined?(:@params)

  return sprintf(
    '%s%s%s',
    @qualifier == DEFAULT_QUALIFIER ? '' : @qualifier,
    @name,
    @params ? @params : ''
  )
end