spf 0.0.47 → 0.0.52

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 CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- NDRiZjE1NWYxNGNhYTc1N2NjODU5YTA4NmMyZjUxNjliMDIxYjlhZg==
5
- data.tar.gz: !binary |-
6
- MmQ4NGVkMTE2MjdkZDA4NzE1ZGJjY2MzZTljMWE1MGRjYWU5N2FhMQ==
2
+ SHA1:
3
+ metadata.gz: b17ea1cbb732cbec18d856f16a3e107ccb7fb994
4
+ data.tar.gz: e160f6ad54fb977fca0fa9d2a9040c573c680ce3
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- NjY4NWJjNWQ0MjAwN2VlMmNjYTc5ZjVkNmNlYjQxZmNkNzlhNGRjMGYxNDEx
10
- M2M1ZGFmZDkyOTQ5NWJlY2QxYmY1NDdlZDIyZmY1Y2UyOWZlYmNmNDBkOWQ2
11
- OTE1OTY5OTlhOTQ5MjhiZDVkMjliZWQ1MzY4NzYwMjgzZjVjM2I=
12
- data.tar.gz: !binary |-
13
- MmE5ZDY4OGYzY2IzZWRiMjI5NDQ3YThlOWM5MGViZGNiZmViM2U5YjBiMTVj
14
- YjkyZGVhZTI0MGMzMDMzY2NhZTBmZjNhYWNjOWE4MTJlMzU5YTk0N2MwMjBh
15
- YmMzYzM2N2I2MWIxNTY2MGFhMmM1NDg0ODE3NThjNDkzZjQyZmU=
6
+ metadata.gz: dc7615918b321907dd7a434a53e36b313e44a07868fb2f64c9a66f0ac2a11b3b6c7d630edf508dfbfb5bf7b93afaac2bb966e2a665ff8f1a8b2fb339feb090f8
7
+ data.tar.gz: bacbe5b5077843edd490606fa853fcaca6a66eee2a03d251b2f3bbc126e94d8c1ce799fe340a600eb27347765ecc0fb145273e266494581dd6dc17c8476a1698
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", "~> 1.8"
14
+ gem "jeweler", "~> 2.0"
15
15
  gem "simplecov", :require => false, :group => :test
16
16
  end
@@ -1,47 +1,55 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- addressable (2.3.7)
5
- builder (3.2.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.8.9)
9
- multipart-post (~> 1.2.0)
10
- git (1.2.9.1)
11
- github_api (0.10.1)
12
- addressable
13
- faraday (~> 0.8.1)
14
- hashie (>= 1.2)
15
- multi_json (~> 1.4)
16
- nokogiri (~> 1.5.2)
17
- oauth2
18
- hashie (3.4.0)
19
- highline (1.7.1)
20
- jeweler (1.8.8)
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 (~> 1.0)
25
+ bundler
23
26
  git (>= 1.2.5)
24
- github_api (= 0.10.1)
27
+ github_api (~> 0.16.0)
25
28
  highline (>= 1.6.15)
26
- nokogiri (= 1.5.10)
29
+ nokogiri (>= 1.5.10)
30
+ psych
27
31
  rake
28
32
  rdoc
29
- json (1.8.2)
30
- jwt (1.3.0)
33
+ semver2
34
+ jwt (2.2.1)
35
+ mime-types (2.99.3)
36
+ mini_portile2 (2.4.0)
31
37
  multi_json (1.10.1)
32
- multi_xml (0.5.5)
33
- multipart-post (1.2.0)
34
- nokogiri (1.5.10)
35
- oauth2 (1.0.0)
36
- faraday (>= 0.8, < 0.10)
37
- jwt (~> 1.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 (~> 1.2)
41
- rack (1.6.0)
47
+ rack (>= 1.2, < 3)
48
+ psych (3.1.0)
49
+ rack (2.2.3)
42
50
  rake (10.4.2)
43
- rdoc (3.12.2)
44
- json (~> 1.4)
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 (~> 1.8)
66
- rdoc (~> 3)
75
+ jeweler (~> 2.0)
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.16.1
@@ -29,7 +29,7 @@ Note: This gem is currently very early in its lifecycle. The API is *not* guara
29
29
 
30
30
  == Copyright
31
31
 
32
- Copyright 2013, 2014 Agari Data, Inc.
32
+ Copyright 2016 Agari Data, Inc.
33
33
 
34
34
  Licensed under the Apache License, Version 2.0 (the "License");
35
35
  you may not use this software except in compliance with the License.
@@ -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 DuplicateGlobalMod < InvalidModError; end # Duplicate global modifier
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 TermIPv4PrefixLengthExpected < SyntaxError; end # Missing required <ip4-cidr-length> in term
60
- class TermIPv6AddressExpected < SyntaxError; end # Missing required <ip6-network> in term
61
- class TermIPv6PrefixLengthExpected < SyntaxError; end # Missing required <ip6-cidr-length> in term
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
@@ -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
- record = klass.new_from_string(text, {:raise_exceptions => @raise_exceptions})
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
@@ -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
- # TODO
48
- return (@expanded = @text)
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 MacroExpansionCtxRequired, 'SPF server object required' if required
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 MacroExpansionCtxRequired, 'SPF request object required' if required
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
 
@@ -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::TermIPv4PrefixLengthExpected.new(
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::TermIPv4PrefixLengthExpected.new(
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::TermIPv6AddressExpected.new(
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::TermIPvPrefixLengthExpected.new(
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
- packet = server.dns_lookup(domain, 'A')
450
- rrs = (packet.exchange or server.count_void_dns_lookup(request))
451
- rrs.each do |rr|
452
- return true if rr.type == 'A'
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
@@ -465,9 +468,11 @@ class SPF::Mech < SPF::Term
465
468
  self.parse_ipv4_network(required)
466
469
  if IP === @ip_network
467
470
  @ip_netblocks << @ip_network
468
- @errors << SPF::InvalidMechCIDRError.new(
469
- "Invalid CIDR netblock - bits in host portion of address of #{@ip_network}"
470
- ) if @ip_network.offset != 0
471
+ if @ip_network.respond_to?(:offset) && @ip_network.offset != 0
472
+ @errors << SPF::InvalidMechCIDRError.new(
473
+ "Invalid CIDR netblock - bits in host portion of address of #{@ip_network}"
474
+ )
475
+ end
471
476
  end
472
477
  end
473
478
 
@@ -498,9 +503,11 @@ class SPF::Mech < SPF::Term
498
503
  def parse_params(required = true)
499
504
  self.parse_ipv6_network(required)
500
505
  @ip_netblocks << @ip_network if IP === @ip_network
501
- @errors << SPF::InvalidMechCIDRError.new(
502
- "Invalid CIDR netblock - bits in host portion of address of #{@ip_network}"
503
- ) if @ip_network.offset != 0
506
+ if @ip_network.respond_to?(:offset) && @ip_network.offset != 0
507
+ @errors << SPF::InvalidMechCIDRError.new(
508
+ "Invalid CIDR netblock - bits in host portion of address of #{@ip_network}"
509
+ )
510
+ end
504
511
  end
505
512
 
506
513
  def params
@@ -571,7 +578,7 @@ class SPF::Mech < SPF::Term
571
578
  return nil unless server and request
572
579
  authority_domain = self.domain(server, request)
573
580
  sub_request = request.new_sub_request({:authority_domain => authority_domain})
574
- return @nested_record = server.selectrecord(sub_request, loose_match)
581
+ return @nested_record = server.select_record(sub_request, loose_match)
575
582
  end
576
583
 
577
584
  end
@@ -840,6 +847,7 @@ class SPF::Record
840
847
  @global_mods ||= {}
841
848
  @errors = []
842
849
  @ip_netblocks = []
850
+ @record_domain = options[:record_domain]
843
851
  @raise_exceptions = options.has_key?(:raise_exceptions) ? options[:raise_exceptions] : true
844
852
  end
845
853
 
@@ -910,7 +918,11 @@ class SPF::Record
910
918
  error(exception)
911
919
  mech_class = SPF::Mech
912
920
  end
913
- term = mech = mech_class.new_from_string(mech_text, {:raise_exceptions => @raise_exceptions})
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)
914
926
  term.errors << exception if exception
915
927
  @ip_netblocks << mech.ip_netblocks if mech.ip_netblocks
916
928
  @terms << mech
@@ -937,7 +949,7 @@ class SPF::Record
937
949
  if SPF::GlobalMod === mod
938
950
  # Global modifier.
939
951
  if @global_mods[mod_name]
940
- raise SPF::DuplicateGlobalMod.new("Duplicate global modifier '#{mod_name}' encountered")
952
+ raise SPF::DuplicateGlobalModError.new("Duplicate global modifier '#{mod_name}' encountered")
941
953
  end
942
954
  @global_mods[mod_name] = mod
943
955
  elsif SPF::PositionalMod === mod
@@ -1,6 +1,6 @@
1
1
  # encoding: ASCII-8BIT
2
2
  module SPF
3
- VERSION = '0.0.47'
3
+ VERSION = '0.0.52'
4
4
  end
5
5
 
6
6
  # vim:sw=2 sts=2
@@ -2,11 +2,11 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: spf 0.0.47 ruby lib
5
+ # stub: spf 0.0.48 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "spf"
9
- s.version = "0.0.47"
9
+ s.version = "0.0.52"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.47
4
+ version: 0.0.52
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Flury
8
8
  - Julian Mehnle
9
9
  - Jacob Rideout
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
  date: 2015-04-29 00:00:00.000000000 Z
@@ -16,74 +16,75 @@ dependencies:
16
16
  name: ruby-ip
17
17
  requirement: !ruby/object:Gem::Requirement
18
18
  requirements:
19
- - - ~>
19
+ - - "~>"
20
20
  - !ruby/object:Gem::Version
21
21
  version: 0.9.1
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
- - - ~>
26
+ - - "~>"
27
27
  - !ruby/object:Gem::Version
28
28
  version: 0.9.1
29
29
  - !ruby/object:Gem::Dependency
30
30
  name: rspec
31
31
  requirement: !ruby/object:Gem::Requirement
32
32
  requirements:
33
- - - ~>
33
+ - - "~>"
34
34
  - !ruby/object:Gem::Version
35
35
  version: '2.9'
36
36
  type: :development
37
37
  prerelease: false
38
38
  version_requirements: !ruby/object:Gem::Requirement
39
39
  requirements:
40
- - - ~>
40
+ - - "~>"
41
41
  - !ruby/object:Gem::Version
42
42
  version: '2.9'
43
43
  - !ruby/object:Gem::Dependency
44
44
  name: rdoc
45
45
  requirement: !ruby/object:Gem::Requirement
46
46
  requirements:
47
- - - ~>
47
+ - - "~>"
48
48
  - !ruby/object:Gem::Version
49
49
  version: '3'
50
50
  type: :development
51
51
  prerelease: false
52
52
  version_requirements: !ruby/object:Gem::Requirement
53
53
  requirements:
54
- - - ~>
54
+ - - "~>"
55
55
  - !ruby/object:Gem::Version
56
56
  version: '3'
57
57
  - !ruby/object:Gem::Dependency
58
58
  name: bundler
59
59
  requirement: !ruby/object:Gem::Requirement
60
60
  requirements:
61
- - - ~>
61
+ - - "~>"
62
62
  - !ruby/object:Gem::Version
63
63
  version: '1.2'
64
64
  type: :development
65
65
  prerelease: false
66
66
  version_requirements: !ruby/object:Gem::Requirement
67
67
  requirements:
68
- - - ~>
68
+ - - "~>"
69
69
  - !ruby/object:Gem::Version
70
70
  version: '1.2'
71
71
  - !ruby/object:Gem::Dependency
72
72
  name: jeweler
73
73
  requirement: !ruby/object:Gem::Requirement
74
74
  requirements:
75
- - - ~>
75
+ - - "~>"
76
76
  - !ruby/object:Gem::Version
77
77
  version: '1.8'
78
78
  type: :development
79
79
  prerelease: false
80
80
  version_requirements: !ruby/object:Gem::Requirement
81
81
  requirements:
82
- - - ~>
82
+ - - "~>"
83
83
  - !ruby/object:Gem::Version
84
84
  version: '1.8'
85
- description: ! " An object-oriented Ruby implementation of the Sender Policy Framework
86
- (SPF)\n e-mail sender authentication system, fully compliant with RFC 4408.\n"
85
+ description: |2
86
+ An object-oriented Ruby implementation of the Sender Policy Framework (SPF)
87
+ e-mail sender authentication system, fully compliant with RFC 4408.
87
88
  email:
88
89
  - code@agari.com
89
90
  - aflury@agari.com
@@ -94,8 +95,8 @@ extensions: []
94
95
  extra_rdoc_files:
95
96
  - README.rdoc
96
97
  files:
97
- - .document
98
- - .rspec
98
+ - ".document"
99
+ - ".rspec"
99
100
  - Gemfile
100
101
  - Gemfile.lock
101
102
  - README.rdoc
@@ -117,25 +118,24 @@ homepage: https://github.com/agaridata/spf-ruby
117
118
  licenses:
118
119
  - none (all rights reserved)
119
120
  metadata: {}
120
- post_install_message:
121
+ post_install_message:
121
122
  rdoc_options: []
122
123
  require_paths:
123
124
  - lib
124
125
  required_ruby_version: !ruby/object:Gem::Requirement
125
126
  requirements:
126
- - - ! '>='
127
+ - - ">="
127
128
  - !ruby/object:Gem::Version
128
129
  version: '0'
129
130
  required_rubygems_version: !ruby/object:Gem::Requirement
130
131
  requirements:
131
- - - ! '>='
132
+ - - ">="
132
133
  - !ruby/object:Gem::Version
133
134
  version: '0'
134
135
  requirements: []
135
- rubyforge_project:
136
- rubygems_version: 2.4.4
137
- signing_key:
136
+ rubyforge_project:
137
+ rubygems_version: 2.5.1
138
+ signing_key:
138
139
  specification_version: 4
139
140
  summary: Implementation of the Sender Policy Framework
140
141
  test_files: []
141
- has_rdoc: