Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does not process redirect global mod correctly #12

Open
scottberke opened this issue Jul 31, 2015 · 2 comments
Open

Does not process redirect global mod correctly #12

scottberke opened this issue Jul 31, 2015 · 2 comments

Comments

@scottberke
Copy link
Contributor

I've spent a significant amount of time trying to debug/fix this issue but the further down the rabbit hole I get, the more I'm worried that I don't fully understand how to handle global modifiers.

If you have an spf record that has includes:gmail.com - Gmail subsequently uses a redirect global modifier redirect=_spf.google.com (the entire txt record is v=spf1 redirect=_spf.google.com)

When this gem goes into SPF::Record#eval there are no @terms for this subrequest so the .each block just returns [] and the rescue SPF::Result => result on line 1001 never gets hit which would break into the processing of the global mods. Result for this subrequest is nil and when that's being raised (since we never processed the global_mod to get a result) we get TypeError: exception object expected

Even when I modify the conditional to check if there are global_mods present but no terms present and then hit global_mod.process(server, request, result) for the one global_mod - SPF::Mod::Redirect seems to incorrectly try and call authority_domain = @domain_spec.new({:server => server, :request => request}) (@domain_spec is already a SPF::MacroString and doesn't respond to new). If SPF::Mod::Redirect is modified to act like SPF::Mech::Include and call
authority_domain = self.domain(server, request) it will try to process all the sub requests for the redirect:_spf.google.com but eventually returns nil which bubbles up through the call stack and I'm eventually left in the same place with nil trying to be raised somewhere along the line which produces TypeError: exception object expected

I would be more than happy to work on this with someone more knowledgeable but at this point I've just followed this so far down the hole to the point that I'm not sure I fully understand what's going on or would be able to without some assistance. 🤘

Here's what happens if you just call the gem without any of the debugging/fixes that I've tried to put in place:

$ be irb                                                                                                                                                                                                 2.2.2
irb(main):001:0> require 'spf'
=> true
irb(main):002:0>  spf_server = SPF::Server.new
=> #<SPF::Server:0x007fbed93910a8 @default_authority_explanation=#<SPF::MacroString:0x007fbed9390fe0 @text="Please see http://www.openspf.org/Why?s=%{_scope};id=%{S};ip=%{C};r=%{R}", @server=#<SPF::Server:0x007fbed93910a8 ...>, @request=nil, @expanded="Please see http://www.openspf.org/Why?s=%{_scope};id=%{S};ip=%{C};r=%{R}">, @hostname="scott-berke-mba.local", @dns_resolver=#<Resolv::DNS:0x007fbed9390bd0 @mutex=#<Mutex:0x007fbed9390b30>, @config=#<Resolv::DNS::Config:0x007fbed9390b08 @mutex=#<Mutex:0x007fbed9390a90>, @config_info=nil, @initialized=nil, @timeouts=nil>, @initialized=nil>, @query_rr_types=1, @max_dns_interactive_terms=10, @max_name_lookups_per_term=10, @max_name_lookups_per_mx_mech=10, @max_name_lookups_per_ptr_mech=10, @max_void_dns_lookups=2, @raise_exceptions=true>
irb(main):003:0> request = SPF::Request.new(
irb(main):004:1*         versions:      [1],
irb(main):005:1*         scope:         'mfrom',
irb(main):006:1*         identity:      "example@gmail.com",
irb(main):007:1*         ip_address:    "167.89.50.131"
irb(main):008:1>       )
=> #<SPF::Request:0x007fbed934aef0 @opt={:versions=>[1], :scope=>"mfrom", :identity=>"example@gmail.com", :ip_address=>"167.89.50.131"}, @state={}, @versions=[1], @scope=:mfrom, @authority_domain=nil, @identity="example@gmail.com", @ip_address=#<IP::V4 167.89.50.131>, @helo_identity=nil, @root_request=#<SPF::Request:0x007fbed934aef0 ...>, @super_request=#<SPF::Request:0x007fbed934aef0 ...>, @record=nil, @sub_requests=[], @localpart="example", @domain="gmail.com", @ip_address_v6=#<IP::V6 ::ffff:167.89.50.131>>
irb(main):009:0>  spf_server.process(request)
TypeError: exception object expected
    from /Users/scottberke/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/spf-0.0.46/lib/spf/model.rb:566:in `raise'
    from /Users/scottberke/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/spf-0.0.46/lib/spf/model.rb:566:in `match'
    from /Users/scottberke/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/spf-0.0.46/lib/spf/model.rb:989:in `block in eval'
    from /Users/scottberke/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/spf-0.0.46/lib/spf/model.rb:985:in `each'
    from /Users/scottberke/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/spf-0.0.46/lib/spf/model.rb:985:in `eval'
    from /Users/scottberke/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/spf-0.0.46/lib/spf/eval.rb:103:in `process'
    from /Users/scottberke/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/spf-0.0.46/lib/spf/model.rb:799:in `process'
    from /Users/scottberke/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/spf-0.0.46/lib/spf/model.rb:1020:in `block in process_global_mods'
    from /Users/scottberke/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/spf-0.0.46/lib/spf/model.rb:1019:in `each'
    from /Users/scottberke/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/spf-0.0.46/lib/spf/model.rb:1019:in `process_global_mods'
    from /Users/scottberke/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/spf-0.0.46/lib/spf/model.rb:983:in `eval'
    from /Users/scottberke/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/spf-0.0.46/lib/spf/eval.rb:103:in `process'
    from (irb):9
    from /Users/scottberke/.rbenv/versions/2.2.2/bin/irb:11:in `<main>'
irb(main):010:0> ```
@scottberke
Copy link
Contributor Author

I apologize - The output above was actually with some of my attempted fixes.
Here is the output from the unmodified gem:
*sugarloafcut.com has the following txt record: v=spf1 include:gmail.com ~all

$ be irb                                                                                                                                                       2.2.2
irb(main):001:0>  require 'spf'
=> true
irb(main):002:0> spf_server = SPF::Server.new
=> #<SPF::Server:0x007fe8e28fd568 @default_authority_explanation=#<SPF::MacroString:0x007fe8e28fd4f0 @text="Please see http://www.openspf.org/Why?s=%{_scope};id=%{S};ip=%{C};r=%{R}", @server=#<SPF::Server:0x007fe8e28fd568 ...>, @request=nil, @expanded="Please see http://www.openspf.org/Why?s=%{_scope};id=%{S};ip=%{C};r=%{R}">, @hostname="scott-berke-mba.local", @dns_resolver=#<Resolv::DNS:0x007fe8e28fd270 @mutex=#<Mutex:0x007fe8e28fd248>, @config=#<Resolv::DNS::Config:0x007fe8e28fd220 @mutex=#<Mutex:0x007fe8e28fd1f8>, @config_info=nil, @initialized=nil, @timeouts=nil>, @initialized=nil>, @query_rr_types=1, @max_dns_interactive_terms=10, @max_name_lookups_per_term=10, @max_name_lookups_per_mx_mech=10, @max_name_lookups_per_ptr_mech=10, @max_void_dns_lookups=2, @raise_exceptions=true>
irb(main):003:0> request = SPF::Request.new(
irb(main):004:1*         versions:      [1],
irb(main):005:1*         scope:         'mfrom',
irb(main):006:1*         identity:      "example@sugarloafcut.com",
irb(main):007:1*         ip_address:    "167.89.50.131"
irb(main):008:1>       )
=> #<SPF::Request:0x007fe8e28cf7a8 @opt={:versions=>[1], :scope=>"mfrom", :identity=>"example@sugarloafcut.com", :ip_address=>"167.89.50.131"}, @state={}, @versions=[1], @scope=:mfrom, @authority_domain=nil, @identity="example@sugarloafcut.com", @ip_address=#<IP::V4 167.89.50.131>, @helo_identity=nil, @root_request=#<SPF::Request:0x007fe8e28cf7a8 ...>, @super_request=#<SPF::Request:0x007fe8e28cf7a8 ...>, @record=nil, @sub_requests=[], @localpart="example", @domain="sugarloafcut.com", @ip_address_v6=#<IP::V6 ::ffff:167.89.50.131>>
irb(main):009:0> 
irb(main):010:0*  spf_server.process(request)
TypeError: exception object expected
    from /Users/scottberke/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/spf-0.0.46/lib/spf/model.rb:566:in `raise'
    from /Users/scottberke/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/spf-0.0.46/lib/spf/model.rb:566:in `match'
    from /Users/scottberke/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/spf-0.0.46/lib/spf/model.rb:988:in `block in eval'
    from /Users/scottberke/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/spf-0.0.46/lib/spf/model.rb:984:in `each'
    from /Users/scottberke/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/spf-0.0.46/lib/spf/model.rb:984:in `eval'
    from /Users/scottberke/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/spf-0.0.46/lib/spf/eval.rb:103:in `process'
    from (irb):10
    from /Users/scottberke/.rbenv/versions/2.2.2/bin/irb:11:in `<main>'

@aflury
Copy link

aflury commented Aug 4, 2015

Thanks for looking into this, and sorry that you wound up in a rabbit hole! Can you try with the latest code? Handling of redirect: modifiers was pretty horribly broken in a couple places.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants