spf-query 0.1.4 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -4
- data/ChangeLog.md +9 -0
- data/LICENSE.txt +2 -2
- data/lib/resolv/dns/resource/in/spf.rb +3 -0
- data/lib/spf/query/exceptions.rb +8 -0
- data/lib/spf/query/ip.rb +23 -0
- data/lib/spf/query/macro.rb +40 -0
- data/lib/spf/query/macro_string.rb +39 -3
- data/lib/spf/query/mechanism.rb +56 -1
- data/lib/spf/query/modifier.rb +26 -0
- data/lib/spf/query/query.rb +1 -1
- data/lib/spf/query/record.rb +3 -0
- data/lib/spf/query/version.rb +2 -1
- data/spec/query_spec.rb +16 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b9a9fddefde5c33a2ad1385bab0d15ca8477ad0a
|
4
|
+
data.tar.gz: ed9f792eb99ef6308b07627645efb7aae4eeb695
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 62515f4dd785031a84487205a3f7d85608464798e53b8667f09c69cf230590d398ccebd5aaf09e95951b1630c3a048268db28b59bde3e601afe40db385730817
|
7
|
+
data.tar.gz: 4647bd4bc4351b6cb2032a7dac1d6b05d51e93e6cafd308423abb07d9118d5c2655057da7d2068074331e81577ee39d44489f90621fadf9cf26ab21c49ccb6ca
|
data/.travis.yml
CHANGED
data/ChangeLog.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
### 0.1.5 / 2016-07-10
|
2
|
+
|
3
|
+
* Fixed a bug in {SPF::Query.query} for when the TXT record is split into
|
4
|
+
multiple strings. According to [RFC 7208, Section 3.3], multiple strings
|
5
|
+
should be joined together _without_ spaces.
|
6
|
+
* Fixed a bug in {SPF::Query::Mechanism#to_s}.
|
7
|
+
|
8
|
+
[RFC 7208, Section 3.3]: https://tools.ietf.org/html/rfc7208#section-3.3
|
9
|
+
|
1
10
|
### 0.1.4 / 2015-12-10
|
2
11
|
|
3
12
|
* Prioritize TXT records on `_spf.example.com` and `example.com` over a SPF
|
data/LICENSE.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
|
-
Copyright (c) 2014 Trail of Bits
|
3
|
+
Copyright (c) 2014-2016 Trail of Bits
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
6
|
this software and associated documentation files (the "Software"), to deal in
|
@@ -17,4 +17,4 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
17
17
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
18
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
19
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
-
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/lib/spf/query/exceptions.rb
CHANGED
@@ -2,9 +2,17 @@ require 'parslet'
|
|
2
2
|
|
3
3
|
module SPF
|
4
4
|
module Query
|
5
|
+
#
|
6
|
+
# Exception for when the SPF record cannot be parsed.
|
7
|
+
#
|
5
8
|
class InvalidRecord < Parslet::ParseFailed
|
6
9
|
end
|
7
10
|
|
11
|
+
#
|
12
|
+
# Exception for when [SenderID] is found in-place of SPF.
|
13
|
+
#
|
14
|
+
# [SenderID]: http://www.openspf.org/SPF_vs_Sender_ID
|
15
|
+
#
|
8
16
|
class SenderIDFound < InvalidRecord
|
9
17
|
end
|
10
18
|
end
|
data/lib/spf/query/ip.rb
CHANGED
@@ -1,16 +1,39 @@
|
|
1
1
|
module SPF
|
2
2
|
module Query
|
3
|
+
#
|
4
|
+
# Represents an IP address in an SPF record.
|
5
|
+
#
|
3
6
|
class IP
|
4
7
|
|
8
|
+
# The address.
|
9
|
+
#
|
10
|
+
# @return [String]
|
5
11
|
attr_reader :address
|
6
12
|
|
13
|
+
# CIDR length.
|
14
|
+
#
|
15
|
+
# @return [Integer, nil]
|
7
16
|
attr_reader :cidr_length
|
8
17
|
|
18
|
+
#
|
19
|
+
# Initializes the IP.
|
20
|
+
#
|
21
|
+
# @param [String] address
|
22
|
+
# The IP address.
|
23
|
+
#
|
24
|
+
# @param [Integer, nil] cidr_length
|
25
|
+
# Optional CIDR length.
|
26
|
+
#
|
9
27
|
def initialize(address,cidr_length=nil)
|
10
28
|
@address = address
|
11
29
|
@cidr_length = cidr_length
|
12
30
|
end
|
13
31
|
|
32
|
+
#
|
33
|
+
# Converts the IP address to a String.
|
34
|
+
#
|
35
|
+
# @return [String]
|
36
|
+
#
|
14
37
|
def to_s
|
15
38
|
if @cidr_length then "#{@address}/#{@cidr_length}"
|
16
39
|
else "#{@address}"
|
data/lib/spf/query/macro.rb
CHANGED
@@ -1,13 +1,43 @@
|
|
1
1
|
module SPF
|
2
2
|
module Query
|
3
|
+
#
|
4
|
+
# Represents an SPF string macro.
|
5
|
+
#
|
3
6
|
class Macro
|
4
7
|
|
8
|
+
# The macro letter.
|
9
|
+
#
|
10
|
+
# @return [Symbol]
|
5
11
|
attr_reader :letter
|
6
12
|
|
13
|
+
# Number of times the macro must be repeated.
|
14
|
+
#
|
15
|
+
# @return [Integer, nil]
|
7
16
|
attr_reader :digits
|
8
17
|
|
18
|
+
# Macro delimiter character.
|
19
|
+
#
|
20
|
+
# @return [Array<String>]
|
9
21
|
attr_reader :delimiters
|
10
22
|
|
23
|
+
#
|
24
|
+
# Initializes the macro.
|
25
|
+
#
|
26
|
+
# @param [Symbol] letter
|
27
|
+
# The macro letter.
|
28
|
+
#
|
29
|
+
# @param [Hash] options
|
30
|
+
# Additional options.
|
31
|
+
#
|
32
|
+
# @option options [Integer] :digits
|
33
|
+
# Number of times to repeat the macro.
|
34
|
+
#
|
35
|
+
# @option options [Boolean] :reverse
|
36
|
+
# Whether to reverse the value.
|
37
|
+
#
|
38
|
+
# @option options [Array<String>, String] :delimiters
|
39
|
+
# Delimiter characters.
|
40
|
+
#
|
11
41
|
def initialize(letter,options={})
|
12
42
|
@letter = letter
|
13
43
|
@digits = options[:digits]
|
@@ -15,10 +45,20 @@ module SPF
|
|
15
45
|
@delimiters = Array(options[:delimiters])
|
16
46
|
end
|
17
47
|
|
48
|
+
#
|
49
|
+
# Specifies if the macro should be reversed.
|
50
|
+
#
|
51
|
+
# @return [Boolean]
|
52
|
+
#
|
18
53
|
def reverse?
|
19
54
|
@reverse
|
20
55
|
end
|
21
56
|
|
57
|
+
#
|
58
|
+
# Converts the macro a String.
|
59
|
+
#
|
60
|
+
# @return [String]
|
61
|
+
#
|
22
62
|
def to_s
|
23
63
|
"%{#{@letter}#{@digits}#{@delimiters.join}}"
|
24
64
|
end
|
@@ -1,29 +1,65 @@
|
|
1
1
|
module SPF
|
2
2
|
module Query
|
3
|
+
#
|
4
|
+
# Represents a string containing SPF macros.
|
5
|
+
#
|
3
6
|
class MacroString
|
4
7
|
|
5
8
|
include Enumerable
|
6
9
|
|
10
|
+
#
|
11
|
+
# Initializes the macro string.
|
12
|
+
#
|
13
|
+
# @param [Array<String, Macro>] elements
|
14
|
+
# String literals and String macros.
|
15
|
+
#
|
7
16
|
def initialize(elements)
|
8
17
|
@elements = elements
|
9
18
|
end
|
10
19
|
|
20
|
+
#
|
21
|
+
# Enumerates over the macro string literals and macros.
|
22
|
+
#
|
23
|
+
# @yield [element]
|
24
|
+
#
|
25
|
+
# @yieldparam [String, Macro] element
|
26
|
+
#
|
27
|
+
# @return [Enumerator]
|
28
|
+
# If no block is given, an Enumerator will be returned.
|
29
|
+
#
|
11
30
|
def each(&block)
|
12
31
|
@elements.each(&block)
|
13
32
|
end
|
14
33
|
|
34
|
+
#
|
35
|
+
# Accesses the String literal or macro at the given index or range.
|
36
|
+
#
|
37
|
+
# @param [Integer, (Integer, Integer), Range] arguments
|
38
|
+
# The index or range to access.
|
39
|
+
#
|
40
|
+
# @return [Array<String, Macro>, String, Macro]
|
41
|
+
# The String literal(s) or macro(s) at the given index or range.
|
42
|
+
#
|
15
43
|
def [](*arguments)
|
16
44
|
@elements[*arguments]
|
17
45
|
end
|
18
46
|
|
47
|
+
#
|
48
|
+
# Converts the macro string to an Array.
|
49
|
+
#
|
50
|
+
# @return [Array<String, Macro>]
|
51
|
+
#
|
19
52
|
def to_a
|
20
53
|
@elements
|
21
54
|
end
|
22
55
|
|
23
|
-
|
24
|
-
@elements
|
25
|
-
end
|
56
|
+
alias to_ary to_a
|
26
57
|
|
58
|
+
#
|
59
|
+
# Converts the macro string to a String.
|
60
|
+
#
|
61
|
+
# @return [String]
|
62
|
+
#
|
27
63
|
def to_s
|
28
64
|
@elements.join
|
29
65
|
end
|
data/lib/spf/query/mechanism.rb
CHANGED
@@ -1,18 +1,42 @@
|
|
1
1
|
module SPF
|
2
2
|
module Query
|
3
|
+
#
|
4
|
+
# Represents an SPF mechanism.
|
5
|
+
#
|
3
6
|
class Mechanism
|
4
7
|
|
8
|
+
# Maps qualifier symbols to Symbols
|
5
9
|
QUALIFIERS = {
|
6
10
|
'+' => :pass,
|
7
11
|
'-' => :fail,
|
8
12
|
'~' => :soft_fail,
|
9
|
-
'?' => :
|
13
|
+
'?' => :neutral
|
10
14
|
}
|
11
15
|
|
16
|
+
# The mechanism name.
|
17
|
+
#
|
18
|
+
# @return [Symbol]
|
12
19
|
attr_reader :name
|
13
20
|
|
21
|
+
# The mechanism value.
|
22
|
+
#
|
23
|
+
# @return [String, MacroString, IP, nil]
|
14
24
|
attr_reader :value
|
15
25
|
|
26
|
+
#
|
27
|
+
# Initializes the mechanism.
|
28
|
+
#
|
29
|
+
# @param [Symbol] name
|
30
|
+
#
|
31
|
+
# @param [Hash] options
|
32
|
+
# Additional options.
|
33
|
+
#
|
34
|
+
# @option options [String, MacroString, IP] :value
|
35
|
+
# Optional value.
|
36
|
+
#
|
37
|
+
# @option options [Symbol] :qualifier
|
38
|
+
# Mechanism qualifier.
|
39
|
+
#
|
16
40
|
def initialize(name,options={})
|
17
41
|
@name = name
|
18
42
|
|
@@ -20,26 +44,57 @@ module SPF
|
|
20
44
|
@qualifier = options[:qualifier]
|
21
45
|
end
|
22
46
|
|
47
|
+
#
|
48
|
+
# The mechanism qualifier.
|
49
|
+
#
|
50
|
+
# @return [:pass, :fail, :soft_fail, :neutral]
|
51
|
+
# The qualifier. Defaults to `:pass`.
|
52
|
+
#
|
23
53
|
def qualifier
|
24
54
|
@qualifier || :pass
|
25
55
|
end
|
26
56
|
|
57
|
+
#
|
58
|
+
# Determines whether the qualifier is a "pass".
|
59
|
+
#
|
60
|
+
# @return [Boolean]
|
61
|
+
#
|
27
62
|
def pass?
|
28
63
|
@qualifier == :pass || @qualifier.nil?
|
29
64
|
end
|
30
65
|
|
66
|
+
#
|
67
|
+
# Determines if the qualifier is a "fail".
|
68
|
+
#
|
69
|
+
# @return [Boolean]
|
70
|
+
#
|
31
71
|
def fail?
|
32
72
|
@qualifier == :fail
|
33
73
|
end
|
34
74
|
|
75
|
+
#
|
76
|
+
# Determines whether the qualifier is a "soft_fail".
|
77
|
+
#
|
78
|
+
# @return [Boolean]
|
79
|
+
#
|
35
80
|
def soft_fail?
|
36
81
|
@qualifier == :soft_fail
|
37
82
|
end
|
38
83
|
|
84
|
+
#
|
85
|
+
# Determines whether the qualifier is a "neutral".
|
86
|
+
#
|
87
|
+
# @return [Boolean]
|
88
|
+
#
|
39
89
|
def neutral?
|
40
90
|
@qualifier == :neutral
|
41
91
|
end
|
42
92
|
|
93
|
+
#
|
94
|
+
# Converts the mechanism to a String.
|
95
|
+
#
|
96
|
+
# @return [String]
|
97
|
+
#
|
43
98
|
def to_s
|
44
99
|
str = "#{QUALIFIERS.invert[@qualifier]}#{@name}"
|
45
100
|
str << ":#{@value}" if value
|
data/lib/spf/query/modifier.rb
CHANGED
@@ -1,15 +1,38 @@
|
|
1
1
|
module SPF
|
2
2
|
module Query
|
3
|
+
#
|
4
|
+
# Represents SPF record modifiers.
|
5
|
+
#
|
3
6
|
class Modifier
|
4
7
|
|
8
|
+
# Modifier name.
|
9
|
+
#
|
10
|
+
# @return [Symbol]
|
5
11
|
attr_reader :name
|
6
12
|
|
13
|
+
# Modifier value.
|
14
|
+
#
|
15
|
+
# @return [String, MacroString, IP, nil]
|
7
16
|
attr_reader :value
|
8
17
|
|
18
|
+
#
|
19
|
+
# Initializes the modifier.
|
20
|
+
#
|
21
|
+
# @param [Symbol] name
|
22
|
+
# Modifier name.
|
23
|
+
#
|
24
|
+
# @param [String, nil] value
|
25
|
+
# Modifier value.
|
26
|
+
#
|
9
27
|
def initialize(name,value=nil)
|
10
28
|
@name, @value = name, value
|
11
29
|
end
|
12
30
|
|
31
|
+
#
|
32
|
+
# Converts the modifier to a String.
|
33
|
+
#
|
34
|
+
# @return [String]
|
35
|
+
#
|
13
36
|
def to_s
|
14
37
|
if @value then "#{@name}=#{@value}"
|
15
38
|
else "#{@name}"
|
@@ -18,6 +41,9 @@ module SPF
|
|
18
41
|
|
19
42
|
end
|
20
43
|
|
44
|
+
#
|
45
|
+
# Represents non-standard modifier names.
|
46
|
+
#
|
21
47
|
class UnknownModifier < Modifier
|
22
48
|
end
|
23
49
|
end
|
data/lib/spf/query/query.rb
CHANGED
data/lib/spf/query/record.rb
CHANGED
data/lib/spf/query/version.rb
CHANGED
data/spec/query_spec.rb
CHANGED
@@ -19,6 +19,22 @@ describe SPF::Query do
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
+
context "when the domain.com has a TXT record" do
|
23
|
+
let(:domain) { 'yahoo.com' }
|
24
|
+
|
25
|
+
it "should return the TXT record containing the SPF record" do
|
26
|
+
expect(subject.query(domain)).to be == %{v=spf1 redirect=_spf.mail.yahoo.com}
|
27
|
+
end
|
28
|
+
|
29
|
+
context "and when the record is split into multiple strings" do
|
30
|
+
let(:domain) { 'fb.com' }
|
31
|
+
|
32
|
+
it "should join the strings, without spaces" do
|
33
|
+
expect(subject.query(domain)).to be == %{v=spf1 ip4:69.171.232.0/24 ip4:199.201.64.23 ip4:192.201.64.23 ip4:69.63.179.25 ip4:69.63.178.128/25 ip4:69.63.184.0/25 ip4:66.220.144.128/25 ip4:66.220.155.128/25 include:spf-00082601.pphosted.com mx -all}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
22
38
|
context "when the domain has a SPF type record" do
|
23
39
|
let(:domain) { 'getlua.com' }
|
24
40
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spf-query
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- nicktitle
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-06-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parslet
|