spf 0.0.49 → 0.0.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/Gemfile +2 -2
- data/Gemfile.lock +47 -34
- data/lib/spf/error.rb +4 -4
- data/lib/spf/eval.rb +7 -1
- data/lib/spf/macro_string.rb +123 -6
- data/lib/spf/model.rb +22 -14
- data/lib/spf/version.rb +1 -1
- data/spf.gemspec +1 -1
- metadata +2 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 9b5b96521a48a4f0b0a78397d6e21ff99d03b9d144df182bfd68b0369046d73e
|
|
4
|
+
data.tar.gz: 17025632b91737a607a5035b9dfd2405bb080eeaee3e8091cd5e71dc4729cd4d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: aea5c665821e18e2724d0d0e92ca02a89347eabc53226135944b9de65b7b20d25f64401128606f49367a718e637b2d425fa6bb2fdb0999b3cbecae72c5698852
|
|
7
|
+
data.tar.gz: f4f74a840d9fbe744d5b2fbf52abb5011f5c75672b648e6d0512450d7261997ee4006a83f707ec50300639972a235b0d261e11ac976bddf5a2eea13db8944150
|
data/Gemfile
CHANGED
|
@@ -9,8 +9,8 @@ gem "ruby-ip", "~> 0.9.1"
|
|
|
9
9
|
# Include everything needed to run rake, tests, features, etc.
|
|
10
10
|
group :development do
|
|
11
11
|
gem "rspec", "~> 2.9"
|
|
12
|
-
gem "rdoc", "~> 3"
|
|
12
|
+
gem "rdoc", "~> 4.3"
|
|
13
13
|
gem "bundler", "~> 1.2"
|
|
14
|
-
gem "jeweler", "~>
|
|
14
|
+
gem "jeweler", "~> 2.3", ">= 2.3.9"
|
|
15
15
|
gem "simplecov", :require => false, :group => :test
|
|
16
16
|
end
|
data/Gemfile.lock
CHANGED
|
@@ -1,47 +1,55 @@
|
|
|
1
1
|
GEM
|
|
2
2
|
remote: http://rubygems.org/
|
|
3
3
|
specs:
|
|
4
|
-
addressable (2.
|
|
5
|
-
builder (3.2.
|
|
4
|
+
addressable (2.4.0)
|
|
5
|
+
builder (3.2.4)
|
|
6
|
+
descendants_tracker (0.0.4)
|
|
7
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
|
6
8
|
diff-lcs (1.2.5)
|
|
7
9
|
docile (1.1.5)
|
|
8
|
-
faraday (0.
|
|
9
|
-
multipart-post (
|
|
10
|
-
git (1.
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
10
|
+
faraday (0.9.2)
|
|
11
|
+
multipart-post (>= 1.2, < 3)
|
|
12
|
+
git (1.7.0)
|
|
13
|
+
rchardet (~> 1.8)
|
|
14
|
+
github_api (0.16.0)
|
|
15
|
+
addressable (~> 2.4.0)
|
|
16
|
+
descendants_tracker (~> 0.0.4)
|
|
17
|
+
faraday (~> 0.8, < 0.10)
|
|
18
|
+
hashie (>= 3.4)
|
|
19
|
+
mime-types (>= 1.16, < 3.0)
|
|
20
|
+
oauth2 (~> 1.0)
|
|
21
|
+
hashie (4.1.0)
|
|
22
|
+
highline (2.0.3)
|
|
23
|
+
jeweler (2.3.9)
|
|
21
24
|
builder
|
|
22
|
-
bundler
|
|
25
|
+
bundler
|
|
23
26
|
git (>= 1.2.5)
|
|
24
|
-
github_api (
|
|
27
|
+
github_api (~> 0.16.0)
|
|
25
28
|
highline (>= 1.6.15)
|
|
26
|
-
nokogiri (
|
|
29
|
+
nokogiri (>= 1.5.10)
|
|
30
|
+
psych
|
|
27
31
|
rake
|
|
28
32
|
rdoc
|
|
29
|
-
|
|
30
|
-
jwt (
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
semver2
|
|
34
|
+
jwt (2.2.2)
|
|
35
|
+
mime-types (2.99.3)
|
|
36
|
+
mini_portile2 (2.4.0)
|
|
37
|
+
multi_json (1.15.0)
|
|
38
|
+
multi_xml (0.6.0)
|
|
39
|
+
multipart-post (2.1.1)
|
|
40
|
+
nokogiri (1.10.10)
|
|
41
|
+
mini_portile2 (~> 2.4.0)
|
|
42
|
+
oauth2 (1.4.4)
|
|
43
|
+
faraday (>= 0.8, < 2.0)
|
|
44
|
+
jwt (>= 1.0, < 3.0)
|
|
38
45
|
multi_json (~> 1.3)
|
|
39
46
|
multi_xml (~> 0.5)
|
|
40
|
-
rack (
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
47
|
+
rack (>= 1.2, < 3)
|
|
48
|
+
psych (3.2.0)
|
|
49
|
+
rack (2.2.3)
|
|
50
|
+
rake (13.0.1)
|
|
51
|
+
rchardet (1.8.0)
|
|
52
|
+
rdoc (4.3.0)
|
|
45
53
|
rspec (2.99.0)
|
|
46
54
|
rspec-core (~> 2.99.0)
|
|
47
55
|
rspec-expectations (~> 2.99.0)
|
|
@@ -51,19 +59,24 @@ GEM
|
|
|
51
59
|
diff-lcs (>= 1.1.3, < 2.0)
|
|
52
60
|
rspec-mocks (2.99.3)
|
|
53
61
|
ruby-ip (0.9.3)
|
|
62
|
+
semver2 (3.4.2)
|
|
54
63
|
simplecov (0.9.2)
|
|
55
64
|
docile (~> 1.1.0)
|
|
56
65
|
multi_json (~> 1.0)
|
|
57
66
|
simplecov-html (~> 0.9.0)
|
|
58
67
|
simplecov-html (0.9.0)
|
|
68
|
+
thread_safe (0.3.6)
|
|
59
69
|
|
|
60
70
|
PLATFORMS
|
|
61
71
|
ruby
|
|
62
72
|
|
|
63
73
|
DEPENDENCIES
|
|
64
74
|
bundler (~> 1.2)
|
|
65
|
-
jeweler (~>
|
|
66
|
-
rdoc (~> 3)
|
|
75
|
+
jeweler (~> 2.3, >= 2.3.9)
|
|
76
|
+
rdoc (~> 4.3)
|
|
67
77
|
rspec (~> 2.9)
|
|
68
78
|
ruby-ip (~> 0.9.1)
|
|
69
79
|
simplecov
|
|
80
|
+
|
|
81
|
+
BUNDLED WITH
|
|
82
|
+
1.17.3
|
data/lib/spf/error.rb
CHANGED
|
@@ -50,15 +50,15 @@ module SPF
|
|
|
50
50
|
class InvalidModError < SyntaxError; end # Invalid modifier
|
|
51
51
|
class InvalidTermError < SyntaxError; end # Invalid term
|
|
52
52
|
class JunkInTermError < SyntaxError; end # Junk encountered in term
|
|
53
|
-
class
|
|
53
|
+
class DuplicateGlobalModError < InvalidModError; end # Duplicate global modifier
|
|
54
54
|
class InvalidMechError < InvalidTermError; end # Invalid mechanism
|
|
55
55
|
class InvalidMechQualifierError < InvalidMechError; end # Invalid mechanism qualifier
|
|
56
56
|
class InvalidMechCIDRError < InvalidMechError; end # Invalid CIDR netblock in mech
|
|
57
57
|
class TermDomainSpecExpectedError < SyntaxError; end # Missing required <domain-spec> in term
|
|
58
58
|
class TermIPv4AddressExpectedError < SyntaxError; end # Missing required <ip4-network> in term
|
|
59
|
-
class
|
|
60
|
-
class
|
|
61
|
-
class
|
|
59
|
+
class TermIPv4PrefixLengthExpectedError < SyntaxError; end # Missing required <ip4-cidr-length> in term
|
|
60
|
+
class TermIPv6AddressExpectedError < SyntaxError; end # Missing required <ip6-network> in term
|
|
61
|
+
class TermIPv6PrefixLengthExpectedError < SyntaxError; end # Missing required <ip6-cidr-length> in term
|
|
62
62
|
class InvalidMacroStringError < SyntaxError; end # Invalid macro string
|
|
63
63
|
class InvalidMacroError < InvalidMacroStringError
|
|
64
64
|
end # Invalid macro
|
data/lib/spf/eval.rb
CHANGED
|
@@ -275,7 +275,13 @@ class SPF::Server
|
|
|
275
275
|
versions.each do |version|
|
|
276
276
|
klass = RECORD_CLASSES_BY_VERSION[version]
|
|
277
277
|
begin
|
|
278
|
-
|
|
278
|
+
options = {:raise_exceptions => @raise_exceptions}
|
|
279
|
+
# A MacroString object for domain indicates this is a nested record.
|
|
280
|
+
# Storing the domain.text maintains an association to the include domain.
|
|
281
|
+
if domain.class == SPF::MacroString
|
|
282
|
+
options[:record_domain] = domain.text
|
|
283
|
+
end
|
|
284
|
+
record = klass.new_from_string(text, options)
|
|
279
285
|
rescue SPF::InvalidRecordVersionError => error
|
|
280
286
|
if text =~ /#{LOOSE_SPF_MATCH_PATTERN}/
|
|
281
287
|
possible_matches << text
|
data/lib/spf/macro_string.rb
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# encoding: ASCII-8BIT
|
|
2
2
|
require 'spf/util'
|
|
3
|
+
require 'spf/error'
|
|
4
|
+
require 'uri'
|
|
5
|
+
|
|
3
6
|
|
|
4
7
|
module SPF
|
|
5
8
|
class MacroString
|
|
@@ -22,8 +25,8 @@ module SPF
|
|
|
22
25
|
or raise ArgumentError, "Missing required 'text' option"
|
|
23
26
|
@server = options[:server]
|
|
24
27
|
@request = options[:request]
|
|
28
|
+
@is_explanation = options[:is_explanation]
|
|
25
29
|
@expanded = nil
|
|
26
|
-
self.expand
|
|
27
30
|
end
|
|
28
31
|
|
|
29
32
|
attr_reader :text, :server, :request
|
|
@@ -43,9 +46,124 @@ module SPF
|
|
|
43
46
|
return (@expanded = @text) unless @text =~ /%/
|
|
44
47
|
# Short-circuit expansion if text has no '%' characters.
|
|
45
48
|
|
|
49
|
+
server, request = context ? context : [@server, @request]
|
|
50
|
+
|
|
51
|
+
valid_context(true, server, request)
|
|
52
|
+
|
|
46
53
|
expanded = ''
|
|
47
|
-
|
|
48
|
-
|
|
54
|
+
|
|
55
|
+
text = @text
|
|
56
|
+
|
|
57
|
+
while m = text.match(/ (.*?) %(.) /x) do
|
|
58
|
+
expanded += m[1]
|
|
59
|
+
key = m[2]
|
|
60
|
+
|
|
61
|
+
if (key == '{')
|
|
62
|
+
if m2 = m.post_match.match(/ (\w|_\p{Alpha}+) ([0-9]+)? (r)? ([.\-+,\/_=])? } /x)
|
|
63
|
+
char, rh_parts, reverse, delimiter = m2.captures
|
|
64
|
+
|
|
65
|
+
# Upper-case macro chars trigger URL-escaping AKA percent-encoding
|
|
66
|
+
# (RFC 4408, 8.1/26):
|
|
67
|
+
do_percent_encode = char =~ /\p{Upper}/
|
|
68
|
+
char.downcase!
|
|
69
|
+
|
|
70
|
+
if char == 's' # RFC 4408, 8.1/19
|
|
71
|
+
value = request.identity
|
|
72
|
+
elsif char == 'l' # RFC 4408, 8.1/19
|
|
73
|
+
value = request.localpart
|
|
74
|
+
elsif char == 'o' # RFC 4408, 8.1/19
|
|
75
|
+
value = request.domain
|
|
76
|
+
elsif char == 'd' # RFC 4408, 8.1/6/4
|
|
77
|
+
value = request.authority_domain
|
|
78
|
+
elsif char == 'i' # RFC 4408, 8.1/20, 8.1/21
|
|
79
|
+
ip_address = request.ip_address
|
|
80
|
+
ip_address = SPF::Util.ipv6_address_to_ipv4(ip_address) if SPF::Util.ipv6_address_is_ipv4_mapped(ip_address)
|
|
81
|
+
if IP::V4 === ip_address
|
|
82
|
+
value = ip_address.to_addr
|
|
83
|
+
elsif IP::V6 === ip_address
|
|
84
|
+
value = ip_address.to_hex.upcase.split('').join('.')
|
|
85
|
+
else
|
|
86
|
+
server.throw_result(:permerror, request, "Unexpected IP address version in request")
|
|
87
|
+
end
|
|
88
|
+
elsif char == 'p' # RFC 4408, 8.1/22
|
|
89
|
+
# According to RFC 7208 the "p" macro letter should not be used (or even published).
|
|
90
|
+
# Here it is left unexpanded and transformers and delimiters are not applied.
|
|
91
|
+
value = '%{' + m2.to_s
|
|
92
|
+
rh_parts = nil
|
|
93
|
+
reverse = nil
|
|
94
|
+
elsif char == 'v' # RFC 4408, 8.1/6/7
|
|
95
|
+
if IP::V4 === request.ip_address
|
|
96
|
+
value = 'in-addr'
|
|
97
|
+
elsif IP::V6 === request.ip_address
|
|
98
|
+
value = 'ip6'
|
|
99
|
+
else
|
|
100
|
+
# Unexpected IP address version.
|
|
101
|
+
server.throw_result(:permerror, request, "Unexpected IP address version in request")
|
|
102
|
+
end
|
|
103
|
+
elsif char == 'h' # RFC 4408, 8.1/6/8
|
|
104
|
+
value = request.helo_identity || 'unknown'
|
|
105
|
+
elsif char == 'c' # RFC 4408, 8.1/20, 8.1/21
|
|
106
|
+
raise SPF::InvalidMacroStringError.new("Illegal 'c' macro in non-explanation macro string '#{@text}'") unless @is_explanation
|
|
107
|
+
ip_address = request.ip_address
|
|
108
|
+
value = SPF::Util::ip_address_to_string(ip_address)
|
|
109
|
+
elsif char == 'r' # RFC 4408, 8.1/23
|
|
110
|
+
value = server.hostname || 'unknown'
|
|
111
|
+
elsif char == 't'
|
|
112
|
+
raise SPF::InvalidMacroStringError.new("Illegal 't' macro in non-explanation macro string '#{@text}'") unless @is_explanation
|
|
113
|
+
value = Time.now.to_i.to_s
|
|
114
|
+
elsif char == '_scope'
|
|
115
|
+
# Scope pseudo macro for internal use only!
|
|
116
|
+
value = request.scope.to_s
|
|
117
|
+
else
|
|
118
|
+
# Unknown macro character.
|
|
119
|
+
raise SPF::InvalidMacroStringError.new("Invalid macro character #{char} in macro string '#{@text}'")
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
if rh_parts || reverse
|
|
123
|
+
delimiter ||= self.class.default_split_delimiters
|
|
124
|
+
list = value.split(delimiter)
|
|
125
|
+
list.reverse! if reverse
|
|
126
|
+
# Extract desired parts:
|
|
127
|
+
if rh_parts && rh_parts.to_i > 0
|
|
128
|
+
list = list.last(rh_parts.to_i)
|
|
129
|
+
end
|
|
130
|
+
if rh_parts && rh_parts.to_i == 0
|
|
131
|
+
raise SPF::InvalidMacroStringError.new("Illegal selection of 0 (zero) right-hand parts in macro string '#{@text}'")
|
|
132
|
+
end
|
|
133
|
+
value = list.join(self.class.default_join_delimiter)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
if do_percent_encode
|
|
137
|
+
unsafe = Regexp.new('^' + self.class.uri_unreserved_chars)
|
|
138
|
+
value = URI.escape(value, unsafe)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
expanded += value
|
|
142
|
+
|
|
143
|
+
text = m2.post_match
|
|
144
|
+
else
|
|
145
|
+
# Invalid macro expression.
|
|
146
|
+
raise SPF::InvalidMacroStringError.new("Invalid macro expression in macro string '#{@text}'")
|
|
147
|
+
end
|
|
148
|
+
elsif key == '-'
|
|
149
|
+
expanded += '-'
|
|
150
|
+
text = m.post_match
|
|
151
|
+
elsif key == '_'
|
|
152
|
+
expanded += ' '
|
|
153
|
+
text = m.post_match
|
|
154
|
+
elsif key == '%'
|
|
155
|
+
expanded += '%'
|
|
156
|
+
text = m.post_match
|
|
157
|
+
else
|
|
158
|
+
# Invalid macro expression.
|
|
159
|
+
pos = m.offset(2).first
|
|
160
|
+
raise SPF::InvalidMacroStringError.new("Invalid macro expression at pos #{pos} in macro string '#{@text}'")
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
expanded += text # Append remaining unmatched characters.
|
|
165
|
+
|
|
166
|
+
context ? expanded : @expanded = expanded
|
|
49
167
|
end
|
|
50
168
|
|
|
51
169
|
def to_s
|
|
@@ -58,16 +176,15 @@ module SPF
|
|
|
58
176
|
|
|
59
177
|
def valid_context(required, server = self.server, request = self.request)
|
|
60
178
|
if not SPF::Server === server
|
|
61
|
-
raise
|
|
179
|
+
raise SPF::MacroExpansionCtxRequiredError.new('SPF server object required') if required
|
|
62
180
|
return false
|
|
63
181
|
end
|
|
64
182
|
if not SPF::Request === request
|
|
65
|
-
raise
|
|
183
|
+
raise SPF::MacroExpansionCtxRequiredError.new('SPF request object required') if required
|
|
66
184
|
return false
|
|
67
185
|
end
|
|
68
186
|
return true
|
|
69
187
|
end
|
|
70
|
-
|
|
71
188
|
end
|
|
72
189
|
end
|
|
73
190
|
|
data/lib/spf/model.rb
CHANGED
|
@@ -86,7 +86,7 @@ class SPF::Term
|
|
|
86
86
|
::
|
|
87
87
|
"
|
|
88
88
|
|
|
89
|
-
attr_reader :errors, :ip_netblocks, :ip_address, :ip_network, :ipv4_prefix_length, :ipv6_prefix_length, :domain_spec, :raw_params
|
|
89
|
+
attr_reader :errors, :ip_netblocks, :ip_address, :ip_network, :ipv4_prefix_length, :ipv6_prefix_length, :domain_spec, :raw_params, :record_domain
|
|
90
90
|
|
|
91
91
|
def initialize(options = {})
|
|
92
92
|
@ip_address = nil
|
|
@@ -97,6 +97,7 @@ class SPF::Term
|
|
|
97
97
|
@errors = []
|
|
98
98
|
@ip_netblocks = []
|
|
99
99
|
@text = options[:text]
|
|
100
|
+
@record_domain = options[:record_domain]
|
|
100
101
|
@raise_exceptions = options.has_key?(:raise_exceptions) ? options[:raise_exceptions] : true
|
|
101
102
|
end
|
|
102
103
|
|
|
@@ -117,6 +118,8 @@ class SPF::Term
|
|
|
117
118
|
domain_spec = $1
|
|
118
119
|
domain_spec.sub!(/^(.*?)\.?$/, $1)
|
|
119
120
|
@domain_spec = SPF::MacroString.new({:text => domain_spec})
|
|
121
|
+
elsif record_domain
|
|
122
|
+
@domain_spec = SPF::MacroString.new({:text => record_domain})
|
|
120
123
|
elsif required
|
|
121
124
|
error(SPF::TermDomainSpecExpectedError.new(
|
|
122
125
|
"Missing required domain-spec in '#{@text}'"))
|
|
@@ -139,13 +142,13 @@ class SPF::Term
|
|
|
139
142
|
if @parse_text.sub!(/^\/(\d+)/, '')
|
|
140
143
|
bits = $1.to_i
|
|
141
144
|
unless bits and bits >= 0 and bits <= 32 and $1 !~ /^0./
|
|
142
|
-
error(SPF::
|
|
145
|
+
error(SPF::TermIPv4PrefixLengthExpectedError.new(
|
|
143
146
|
"Invalid IPv4 prefix length encountered in '#{@text}'"))
|
|
144
147
|
return
|
|
145
148
|
end
|
|
146
149
|
@ipv4_prefix_length = bits
|
|
147
150
|
elsif required
|
|
148
|
-
error(SPF::
|
|
151
|
+
error(SPF::TermIPv4PrefixLengthExpectedError.new(
|
|
149
152
|
"Missing required IPv4 prefix length in '#{@text}"))
|
|
150
153
|
return
|
|
151
154
|
else
|
|
@@ -168,7 +171,7 @@ class SPF::Term
|
|
|
168
171
|
if @parse_text.sub!(/(#{IPV6_ADDRESS_PATTERN})(?=\/|$)/x, '')
|
|
169
172
|
@ip_address = $1
|
|
170
173
|
elsif required
|
|
171
|
-
error(SPF::
|
|
174
|
+
error(SPF::TermIPv6AddressExpectedError.new(
|
|
172
175
|
"Missing or invalid required IPv6 address in '#{@text}'"))
|
|
173
176
|
end
|
|
174
177
|
@ip_address = @parse_text.dup unless @ip_address
|
|
@@ -184,7 +187,7 @@ class SPF::Term
|
|
|
184
187
|
end
|
|
185
188
|
@ipv6_prefix_length = bits
|
|
186
189
|
elsif required
|
|
187
|
-
error(SPF::
|
|
190
|
+
error(SPF::TermIPv6PrefixLengthExpectedError.new(
|
|
188
191
|
"Missing required IPv6 prefix length in '#{@text}'"))
|
|
189
192
|
return
|
|
190
193
|
else
|
|
@@ -214,7 +217,7 @@ class SPF::Term
|
|
|
214
217
|
|
|
215
218
|
def domain(server, request)
|
|
216
219
|
if self.instance_variable_defined?(:@domain_spec) and @domain_spec
|
|
217
|
-
return @domain_spec
|
|
220
|
+
return SPF::MacroString.new({:server => server, :request => request, :text => @domain_spec.text})
|
|
218
221
|
end
|
|
219
222
|
return request.authority_domain
|
|
220
223
|
end
|
|
@@ -446,13 +449,13 @@ class SPF::Mech < SPF::Term
|
|
|
446
449
|
server.count_dns_interactive_term(request)
|
|
447
450
|
|
|
448
451
|
domain = self.domain(server, request)
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
452
|
+
begin
|
|
453
|
+
rrs = server.dns_lookup(domain, 'A')
|
|
454
|
+
return true if rrs.any?
|
|
455
|
+
rescue SPF::DNSNXDomainError => e
|
|
456
|
+
server.count_void_dns_lookup(request)
|
|
457
|
+
return false
|
|
453
458
|
end
|
|
454
|
-
|
|
455
|
-
return false
|
|
456
459
|
end
|
|
457
460
|
|
|
458
461
|
end
|
|
@@ -844,6 +847,7 @@ class SPF::Record
|
|
|
844
847
|
@global_mods ||= {}
|
|
845
848
|
@errors = []
|
|
846
849
|
@ip_netblocks = []
|
|
850
|
+
@record_domain = options[:record_domain]
|
|
847
851
|
@raise_exceptions = options.has_key?(:raise_exceptions) ? options[:raise_exceptions] : true
|
|
848
852
|
end
|
|
849
853
|
|
|
@@ -914,7 +918,11 @@ class SPF::Record
|
|
|
914
918
|
error(exception)
|
|
915
919
|
mech_class = SPF::Mech
|
|
916
920
|
end
|
|
917
|
-
|
|
921
|
+
options = {:raise_exceptions => @raise_exceptions}
|
|
922
|
+
if instance_variable_defined?("@record_domain")
|
|
923
|
+
options[:record_domain] = @record_domain
|
|
924
|
+
end
|
|
925
|
+
term = mech = mech_class.new_from_string(mech_text, options)
|
|
918
926
|
term.errors << exception if exception
|
|
919
927
|
@ip_netblocks << mech.ip_netblocks if mech.ip_netblocks
|
|
920
928
|
@terms << mech
|
|
@@ -941,7 +949,7 @@ class SPF::Record
|
|
|
941
949
|
if SPF::GlobalMod === mod
|
|
942
950
|
# Global modifier.
|
|
943
951
|
if @global_mods[mod_name]
|
|
944
|
-
raise SPF::
|
|
952
|
+
raise SPF::DuplicateGlobalModError.new("Duplicate global modifier '#{mod_name}' encountered")
|
|
945
953
|
end
|
|
946
954
|
@global_mods[mod_name] = mod
|
|
947
955
|
elsif SPF::PositionalMod === mod
|
data/lib/spf/version.rb
CHANGED
data/spf.gemspec
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: spf
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.53
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrew Flury
|
|
@@ -133,8 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
133
133
|
- !ruby/object:Gem::Version
|
|
134
134
|
version: '0'
|
|
135
135
|
requirements: []
|
|
136
|
-
|
|
137
|
-
rubygems_version: 2.4.6
|
|
136
|
+
rubygems_version: 3.0.6
|
|
138
137
|
signing_key:
|
|
139
138
|
specification_version: 4
|
|
140
139
|
summary: Implementation of the Sender Policy Framework
|