coppertone 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0b252230ab963c880a9621e06ccab4e80228df66
4
- data.tar.gz: 4429d3c99f23114ee76ae1a3ebb9e8523fabcac2
3
+ metadata.gz: f008edbec530072ac470e674b2ac2b97732809bf
4
+ data.tar.gz: a211786a871481a84b7c7c786c3da0c34b4d0b35
5
5
  SHA512:
6
- metadata.gz: a81f77d79f3f6892093d051db6056412fd1b11906e15a923e7dfb0ab8e027be83aedfd0a680d0b794cee045acf940717cc9695747d0607cab7fae560da34b9ce
7
- data.tar.gz: f539aa4c5f74a5469cafb28a66aa58b056e6cd4a4c071f0e14dd8be1e780dd4f8df20997d5b1948e4230469e11d8381ddfa5f2a28c59a12be02d1e1b3f3ea98a
6
+ metadata.gz: 8b94b130d7f3e834cc2ceca9f27391524036f266294d622499014ef59b330be1250fd5b993f98f992432c1d5c5c859b9009bcf864562c0ce329a355ed59f1df8
7
+ data.tar.gz: 251a6a4f25c5e46313a7e598c2be17ae347b6b4e56e535f76d900c2d2c8e34cccfd64102da00cca0aa1c25de6a737ce993c7aabf9d58682a9281b92ae9f88a02
data/.codeclimate.yml ADDED
@@ -0,0 +1,28 @@
1
+ ---
2
+ engines:
3
+ duplication:
4
+ enabled: true
5
+ config:
6
+ languages:
7
+ - ruby
8
+ - javascript
9
+ - python
10
+ - php
11
+ fixme:
12
+ enabled: true
13
+ rubocop:
14
+ enabled: true
15
+ ratings:
16
+ paths:
17
+ - Gemfile.lock
18
+ - "**.css"
19
+ - "**.inc"
20
+ - "**.js"
21
+ - "**.jsx"
22
+ - "**.module"
23
+ - "**.php"
24
+ - "**.py"
25
+ - "**.rb"
26
+ exclude_paths:
27
+ - coverage/
28
+ - spec/
data/.rubocop.yml CHANGED
@@ -21,3 +21,8 @@ Style/FrozenStringLiteralComment:
21
21
  Style/FileName:
22
22
  Exclude:
23
23
  - 'spec/open_spf/**/*'
24
+ Style/FormatStringToken:
25
+ Enabled: false
26
+ Style/SymbolArray:
27
+ Exclude:
28
+ - 'spec/open_spf/**/*'
data/LICENSE CHANGED
@@ -1,201 +1,21 @@
1
- Apache License
2
- Version 2.0, January 2004
3
- http://www.apache.org/licenses/
4
-
5
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
-
7
- 1. Definitions.
8
-
9
- "License" shall mean the terms and conditions for use, reproduction,
10
- and distribution as defined by Sections 1 through 9 of this document.
11
-
12
- "Licensor" shall mean the copyright owner or entity authorized by
13
- the copyright owner that is granting the License.
14
-
15
- "Legal Entity" shall mean the union of the acting entity and all
16
- other entities that control, are controlled by, or are under common
17
- control with that entity. For the purposes of this definition,
18
- "control" means (i) the power, direct or indirect, to cause the
19
- direction or management of such entity, whether by contract or
20
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
- outstanding shares, or (iii) beneficial ownership of such entity.
22
-
23
- "You" (or "Your") shall mean an individual or Legal Entity
24
- exercising permissions granted by this License.
25
-
26
- "Source" form shall mean the preferred form for making modifications,
27
- including but not limited to software source code, documentation
28
- source, and configuration files.
29
-
30
- "Object" form shall mean any form resulting from mechanical
31
- transformation or translation of a Source form, including but
32
- not limited to compiled object code, generated documentation,
33
- and conversions to other media types.
34
-
35
- "Work" shall mean the work of authorship, whether in Source or
36
- Object form, made available under the License, as indicated by a
37
- copyright notice that is included in or attached to the work
38
- (an example is provided in the Appendix below).
39
-
40
- "Derivative Works" shall mean any work, whether in Source or Object
41
- form, that is based on (or derived from) the Work and for which the
42
- editorial revisions, annotations, elaborations, or other modifications
43
- represent, as a whole, an original work of authorship. For the purposes
44
- of this License, Derivative Works shall not include works that remain
45
- separable from, or merely link (or bind by name) to the interfaces of,
46
- the Work and Derivative Works thereof.
47
-
48
- "Contribution" shall mean any work of authorship, including
49
- the original version of the Work and any modifications or additions
50
- to that Work or Derivative Works thereof, that is intentionally
51
- submitted to Licensor for inclusion in the Work by the copyright owner
52
- or by an individual or Legal Entity authorized to submit on behalf of
53
- the copyright owner. For the purposes of this definition, "submitted"
54
- means any form of electronic, verbal, or written communication sent
55
- to the Licensor or its representatives, including but not limited to
56
- communication on electronic mailing lists, source code control systems,
57
- and issue tracking systems that are managed by, or on behalf of, the
58
- Licensor for the purpose of discussing and improving the Work, but
59
- excluding communication that is conspicuously marked or otherwise
60
- designated in writing by the copyright owner as "Not a Contribution."
61
-
62
- "Contributor" shall mean Licensor and any individual or Legal Entity
63
- on behalf of whom a Contribution has been received by Licensor and
64
- subsequently incorporated within the Work.
65
-
66
- 2. Grant of Copyright License. Subject to the terms and conditions of
67
- this License, each Contributor hereby grants to You a perpetual,
68
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
- copyright license to reproduce, prepare Derivative Works of,
70
- publicly display, publicly perform, sublicense, and distribute the
71
- Work and such Derivative Works in Source or Object form.
72
-
73
- 3. Grant of Patent License. Subject to the terms and conditions of
74
- this License, each Contributor hereby grants to You a perpetual,
75
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
- (except as stated in this section) patent license to make, have made,
77
- use, offer to sell, sell, import, and otherwise transfer the Work,
78
- where such license applies only to those patent claims licensable
79
- by such Contributor that are necessarily infringed by their
80
- Contribution(s) alone or by combination of their Contribution(s)
81
- with the Work to which such Contribution(s) was submitted. If You
82
- institute patent litigation against any entity (including a
83
- cross-claim or counterclaim in a lawsuit) alleging that the Work
84
- or a Contribution incorporated within the Work constitutes direct
85
- or contributory patent infringement, then any patent licenses
86
- granted to You under this License for that Work shall terminate
87
- as of the date such litigation is filed.
88
-
89
- 4. Redistribution. You may reproduce and distribute copies of the
90
- Work or Derivative Works thereof in any medium, with or without
91
- modifications, and in Source or Object form, provided that You
92
- meet the following conditions:
93
-
94
- (a) You must give any other recipients of the Work or
95
- Derivative Works a copy of this License; and
96
-
97
- (b) You must cause any modified files to carry prominent notices
98
- stating that You changed the files; and
99
-
100
- (c) You must retain, in the Source form of any Derivative Works
101
- that You distribute, all copyright, patent, trademark, and
102
- attribution notices from the Source form of the Work,
103
- excluding those notices that do not pertain to any part of
104
- the Derivative Works; and
105
-
106
- (d) If the Work includes a "NOTICE" text file as part of its
107
- distribution, then any Derivative Works that You distribute must
108
- include a readable copy of the attribution notices contained
109
- within such NOTICE file, excluding those notices that do not
110
- pertain to any part of the Derivative Works, in at least one
111
- of the following places: within a NOTICE text file distributed
112
- as part of the Derivative Works; within the Source form or
113
- documentation, if provided along with the Derivative Works; or,
114
- within a display generated by the Derivative Works, if and
115
- wherever such third-party notices normally appear. The contents
116
- of the NOTICE file are for informational purposes only and
117
- do not modify the License. You may add Your own attribution
118
- notices within Derivative Works that You distribute, alongside
119
- or as an addendum to the NOTICE text from the Work, provided
120
- that such additional attribution notices cannot be construed
121
- as modifying the License.
122
-
123
- You may add Your own copyright statement to Your modifications and
124
- may provide additional or different license terms and conditions
125
- for use, reproduction, or distribution of Your modifications, or
126
- for any such Derivative Works as a whole, provided Your use,
127
- reproduction, and distribution of the Work otherwise complies with
128
- the conditions stated in this License.
129
-
130
- 5. Submission of Contributions. Unless You explicitly state otherwise,
131
- any Contribution intentionally submitted for inclusion in the Work
132
- by You to the Licensor shall be under the terms and conditions of
133
- this License, without any additional terms or conditions.
134
- Notwithstanding the above, nothing herein shall supersede or modify
135
- the terms of any separate license agreement you may have executed
136
- with Licensor regarding such Contributions.
137
-
138
- 6. Trademarks. This License does not grant permission to use the trade
139
- names, trademarks, service marks, or product names of the Licensor,
140
- except as required for reasonable and customary use in describing the
141
- origin of the Work and reproducing the content of the NOTICE file.
142
-
143
- 7. Disclaimer of Warranty. Unless required by applicable law or
144
- agreed to in writing, Licensor provides the Work (and each
145
- Contributor provides its Contributions) on an "AS IS" BASIS,
146
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
- implied, including, without limitation, any warranties or conditions
148
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
- PARTICULAR PURPOSE. You are solely responsible for determining the
150
- appropriateness of using or redistributing the Work and assume any
151
- risks associated with Your exercise of permissions under this License.
152
-
153
- 8. Limitation of Liability. In no event and under no legal theory,
154
- whether in tort (including negligence), contract, or otherwise,
155
- unless required by applicable law (such as deliberate and grossly
156
- negligent acts) or agreed to in writing, shall any Contributor be
157
- liable to You for damages, including any direct, indirect, special,
158
- incidental, or consequential damages of any character arising as a
159
- result of this License or out of the use or inability to use the
160
- Work (including but not limited to damages for loss of goodwill,
161
- work stoppage, computer failure or malfunction, or any and all
162
- other commercial damages or losses), even if such Contributor
163
- has been advised of the possibility of such damages.
164
-
165
- 9. Accepting Warranty or Additional Liability. While redistributing
166
- the Work or Derivative Works thereof, You may choose to offer,
167
- and charge a fee for, acceptance of support, warranty, indemnity,
168
- or other liability obligations and/or rights consistent with this
169
- License. However, in accepting such obligations, You may act only
170
- on Your own behalf and on Your sole responsibility, not on behalf
171
- of any other Contributor, and only if You agree to indemnify,
172
- defend, and hold each Contributor harmless for any liability
173
- incurred by, or claims asserted against, such Contributor by reason
174
- of your accepting any such warranty or additional liability.
175
-
176
- END OF TERMS AND CONDITIONS
177
-
178
- APPENDIX: How to apply the Apache License to your work.
179
-
180
- To apply the Apache License to your work, attach the following
181
- boilerplate notice, with the fields enclosed by brackets "{}"
182
- replaced with your own identifying information. (Don't include
183
- the brackets!) The text should be enclosed in the appropriate
184
- comment syntax for the file format. We also recommend that a
185
- file or class name and description of purpose be included on the
186
- same "printed page" as the copyright notice for easier
187
- identification within third-party archives.
188
-
189
- Copyright 2014 Peter M. Goldstein
190
-
191
- Licensed under the Apache License, Version 2.0 (the "License");
192
- you may not use this file except in compliance with the License.
193
- You may obtain a copy of the License at
194
-
195
- http://www.apache.org/licenses/LICENSE-2.0
196
-
197
- Unless required by applicable law or agreed to in writing, software
198
- distributed under the License is distributed on an "AS IS" BASIS,
199
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
- See the License for the specific language governing permissions and
201
- limitations under the License.
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 ValiMail Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/coppertone.gemspec CHANGED
@@ -1,4 +1,5 @@
1
1
  # coding: utf-8
2
+
2
3
  lib = File.expand_path('../lib', __FILE__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'coppertone/version'
@@ -7,11 +8,11 @@ Gem::Specification.new do |spec|
7
8
  spec.name = 'coppertone'
8
9
  spec.version = Coppertone::VERSION
9
10
  spec.authors = ['Peter M. Goldstein']
10
- spec.email = ['peter.m.goldstein@gmail.com']
11
+ spec.email = ['peter@valimail.com']
11
12
  spec.summary = 'A Sender Policy Framework (SPF) toolkit'
12
13
  spec.description = 'Coppertone includes tools for parsing SPF DNS records, evaluating the result of SPF checks for received emails, and creating appropriate email headers from SPF results.'
13
- spec.homepage = 'https://github.com/petergoldstein/coppertone'
14
- spec.license = 'Apache'
14
+ spec.homepage = 'https://github.com/ValiMail/coppertone'
15
+ spec.license = 'MIT'
15
16
  spec.files = `git ls-files -z`.split("\x0")
16
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
@@ -18,7 +18,7 @@ module Coppertone
18
18
  raise Coppertone::DomainSpecParsingError
19
19
  end
20
20
 
21
- EXP_ONLY_MACRO_LETTERS = %w(c r t).freeze
21
+ EXP_ONLY_MACRO_LETTERS = %w[c r t].freeze
22
22
  def only_allowed_macros?
23
23
  @macros.select { |m| m.is_a?(Coppertone::MacroString::MacroExpand) }
24
24
  .none? { |m| EXP_ONLY_MACRO_LETTERS.include?(m.macro_letter) }
@@ -37,7 +37,7 @@ module Coppertone
37
37
  end
38
38
 
39
39
  RESERVED_REGEXP = Regexp.new("[^#{URI::PATTERN::UNRESERVED}]")
40
- %w(s l o d i v h c r t).each do |m|
40
+ %w[s l o d i v h c r t].each do |m|
41
41
  define_method(m.upcase) do
42
42
  unencoded = send(m)
43
43
  unencoded ? ::URI.escape(unencoded, RESERVED_REGEXP) : nil
@@ -9,7 +9,7 @@ module Coppertone
9
9
  # grammer defined in section 7.1.
10
10
  class MacroExpand
11
11
  MACRO_LETTER_CHAR_SET = '[slodiphcrtvSLODIPHCRTV]'.freeze
12
- PTR_MACRO_CHAR_SET = %w(p P).freeze
12
+ PTR_MACRO_CHAR_SET = %w[p P].freeze
13
13
  DELIMITER_CHAR_SET = '[\.\-\+\,\/\_\=]'.freeze
14
14
  VALID_BODY_REGEXP =
15
15
  /\A(#{MACRO_LETTER_CHAR_SET})(\d*)(r?)(#{DELIMITER_CHAR_SET}*)\z/
@@ -38,7 +38,7 @@ module Coppertone
38
38
  @s = @s[(closing_index + 1)..-1]
39
39
  end
40
40
 
41
- SIMPLE_MACRO_LETTERS = %w(% _ -).freeze
41
+ SIMPLE_MACRO_LETTERS = %w[% _ -].freeze
42
42
  def parse_interpolated_macro
43
43
  raise MacroStringParsingError if @s.length == 1
44
44
  macro_code = @s[0, 2]
@@ -28,7 +28,7 @@ module Coppertone
28
28
  # Replaces '%-' in a macro string
29
29
  URL_ENCODED_SPACE_MACRO = new('%-'.freeze, '%20'.freeze)
30
30
 
31
- SIMPLE_INTERPOLATED_MACRO_LETTERS = %w(% _ -).freeze
31
+ SIMPLE_INTERPOLATED_MACRO_LETTERS = %w[% _ -].freeze
32
32
  def self.exists_for?(x)
33
33
  return false unless x && (x.length == 2) && (x[0] == '%')
34
34
  SIMPLE_INTERPOLATED_MACRO_LETTERS.include?(x[1])
@@ -3,7 +3,7 @@ module Coppertone
3
3
  # do not have contextual dependence.
4
4
  class NullMacroContext
5
5
  RESERVED_REGEXP = Regexp.new("[^#{URI::PATTERN::UNRESERVED}]")
6
- %w(s l o d i p v h c r t).each do |m|
6
+ %w[s l o d i p v h c r t].each do |m|
7
7
  define_method(m.upcase) do
8
8
  raise ArgumentError
9
9
  end
@@ -45,7 +45,7 @@ module Coppertone
45
45
  Result.new(:neutral)
46
46
  end
47
47
 
48
- %w(none pass fail softfail neutral temperror permerror).each do |t|
48
+ %w[none pass fail softfail neutral temperror permerror].each do |t|
49
49
  define_method("#{t}?") do
50
50
  self.class.const_get(t.upcase) == send(:code)
51
51
  end
@@ -11,7 +11,7 @@ module Coppertone
11
11
  end
12
12
 
13
13
  def tokens
14
- text.split(/ /).select { |s| !s.blank? }
14
+ text.split(/ /).reject(&:blank?)
15
15
  end
16
16
 
17
17
  def parse_token(token)
@@ -49,7 +49,7 @@ module Coppertone
49
49
  ips = recs.map do |r|
50
50
  IPAddr.new(r[:address]).mask(cidr_length.to_i)
51
51
  end
52
- ips.select { |i| !i.nil? }
52
+ ips.reject(&:nil?)
53
53
  end
54
54
  end
55
55
  end
@@ -1,3 +1,3 @@
1
1
  module Coppertone
2
- VERSION = '0.0.8'.freeze
2
+ VERSION = '0.0.9'.freeze
3
3
  end
@@ -26,7 +26,7 @@ describe Coppertone::DomainSpec do
26
26
  end
27
27
 
28
28
  it 'raises an error when the macro string contains forbidden macros' do
29
- %w(c r t).each do |m|
29
+ %w[c r t].each do |m|
30
30
  expect do
31
31
  Coppertone::DomainSpec.new("%{#{m}}")
32
32
  end.to raise_error(Coppertone::DomainSpecParsingError)
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Coppertone::MacroString::MacroStaticExpand do
4
4
  context '#exists_for?' do
5
- %w(%% %_ %-).each do |x|
5
+ %w[%% %_ %-].each do |x|
6
6
  it "should resolve a macro for the key #{x}" do
7
7
  expect(Coppertone::MacroString::MacroStaticExpand.exists_for?(x))
8
8
  .to eq(true)
@@ -16,7 +16,7 @@ describe Coppertone::MacroString::MacroStaticExpand do
16
16
  end
17
17
 
18
18
  context 'macro_for' do
19
- %w(%% %_ %-).each do |x|
19
+ %w[%% %_ %-].each do |x|
20
20
  it "should resolve a macro for the key #{x}" do
21
21
  expect(Coppertone::MacroString::MacroStaticExpand.macro_for(x))
22
22
  .not_to be_nil
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Coppertone::NullMacroContext do
4
- %w(s l o d i p v h c r t).each do |i|
4
+ %w[s l o d i p v h c r t].each do |i|
5
5
  it "should raise an error for #{i}" do
6
6
  expect do
7
7
  Coppertone::NullMacroContext::NULL_CONTEXT.send(i)
data/spec/record_spec.rb CHANGED
@@ -141,7 +141,7 @@ describe Coppertone::Record do
141
141
  .new('v=spf1 include:_spf.domain1.com ip4:1.2.3.4 include:_spf.domain2.com ~all exp=explain._spf.%{d}')
142
142
  includes = r.includes
143
143
  expect(includes.map(&:mechanism).all? { |i| i.is_a?(Coppertone::Mechanism::Include) }).to be_truthy
144
- expect(includes.map(&:target_domain)).to eq(%w(_spf.domain1.com _spf.domain2.com))
144
+ expect(includes.map(&:target_domain)).to eq(%w[_spf.domain1.com _spf.domain2.com])
145
145
  end
146
146
  end
147
147
 
data/spec/term_spec.rb CHANGED
@@ -29,7 +29,7 @@ describe Coppertone::Term do
29
29
  token = SecureRandom.hex(10)
30
30
  expect(Coppertone::Directive)
31
31
  .to receive(:matching_term).with(token)
32
- .and_raise(Coppertone::Error)
32
+ .and_raise(Coppertone::Error)
33
33
  expect do
34
34
  Coppertone::Term.build_from_token(token)
35
35
  end.to raise_error(Coppertone::Error)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coppertone
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter M. Goldstein
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-22 00:00:00.000000000 Z
11
+ date: 2017-07-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dns_adapter
@@ -126,11 +126,12 @@ description: Coppertone includes tools for parsing SPF DNS records, evaluating t
126
126
  result of SPF checks for received emails, and creating appropriate email headers
127
127
  from SPF results.
128
128
  email:
129
- - peter.m.goldstein@gmail.com
129
+ - peter@valimail.com
130
130
  executables: []
131
131
  extensions: []
132
132
  extra_rdoc_files: []
133
133
  files:
134
+ - ".codeclimate.yml"
134
135
  - ".gitignore"
135
136
  - ".rubocop.yml"
136
137
  - ".travis.yml"
@@ -248,9 +249,9 @@ files:
248
249
  - spec/utils/host_utils_spec.rb
249
250
  - spec/utils/ip_in_domain_checker_spec.rb
250
251
  - spec/utils/validated_domain_finder_spec.rb
251
- homepage: https://github.com/petergoldstein/coppertone
252
+ homepage: https://github.com/ValiMail/coppertone
252
253
  licenses:
253
- - Apache
254
+ - MIT
254
255
  metadata: {}
255
256
  post_install_message:
256
257
  rdoc_options: []
@@ -268,7 +269,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
268
269
  version: '0'
269
270
  requirements: []
270
271
  rubyforge_project:
271
- rubygems_version: 2.6.8
272
+ rubygems_version: 2.6.11
272
273
  signing_key:
273
274
  specification_version: 4
274
275
  summary: A Sender Policy Framework (SPF) toolkit