dkim-query 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +51 -0
- data/.rspec +1 -0
- data/.travis.yml +17 -0
- data/.yardopts +1 -0
- data/ChangeLog.md +3 -0
- data/Gemfile +17 -0
- data/LICENSE.txt +20 -0
- data/README.md +98 -0
- data/Rakefile +23 -0
- data/bin/dkim-query +34 -0
- data/dkim-query.gemspec +26 -0
- data/lib/dkim/query/domain.rb +138 -0
- data/lib/dkim/query/exceptions.rb +8 -0
- data/lib/dkim/query/key.rb +135 -0
- data/lib/dkim/query/malformed_key.rb +33 -0
- data/lib/dkim/query/parser.rb +163 -0
- data/lib/dkim/query/query.rb +60 -0
- data/lib/dkim/query/version.rb +5 -0
- data/lib/dkim/query.rb +4 -0
- data/spec/domain_spec.rb +96 -0
- data/spec/key_spec.rb +91 -0
- data/spec/parser_spec.rb +243 -0
- data/spec/query_spec.rb +60 -0
- data/spec/spec_helper.rb +13 -0
- data/tasks/alexa.rb +43 -0
- metadata +118 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6a9a19d4d8e858912741c97e5aa6327db4384823
|
4
|
+
data.tar.gz: 9d89cefe4db5f22c1de6b6b75b006634b4f4b708
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8a48826f63465c69a2f098d4ad644ad7a750cc7f9fc33af0fa28cdd1da8aaec03132d1fae5d8d237625c9267669dc3f2e1648dbfc385dd87370d8420b336ad50
|
7
|
+
data.tar.gz: 9cebe26aeb4cedcb2bcd5991636b103271da72fcd92bcda9dea3e4cdded337d082dda9d041125a2f21ee89866a3a07e136f0ec0f93b8b26d8be6dfd869b20bbc
|
data/.gitignore
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
<<<<<<< HEAD
|
2
|
+
/.bundle/
|
3
|
+
/.yardoc
|
4
|
+
/Gemfile.lock
|
5
|
+
/_yardoc/
|
6
|
+
/coverage/
|
7
|
+
/doc/
|
8
|
+
/pkg/
|
9
|
+
/spec/reports/
|
10
|
+
/tmp/
|
11
|
+
*.bundle
|
12
|
+
*.so
|
13
|
+
*.o
|
14
|
+
*.a
|
15
|
+
mkmf.log
|
16
|
+
=======
|
17
|
+
*.gem
|
18
|
+
*.rbc
|
19
|
+
/.config
|
20
|
+
/coverage/
|
21
|
+
/InstalledFiles
|
22
|
+
/pkg/
|
23
|
+
/spec/reports/
|
24
|
+
/test/tmp/
|
25
|
+
/test/version_tmp/
|
26
|
+
/tmp/
|
27
|
+
|
28
|
+
## Specific to RubyMotion:
|
29
|
+
.dat*
|
30
|
+
.repl_history
|
31
|
+
build/
|
32
|
+
|
33
|
+
## Documentation cache and generated files:
|
34
|
+
/.yardoc/
|
35
|
+
/_yardoc/
|
36
|
+
/doc/
|
37
|
+
/rdoc/
|
38
|
+
|
39
|
+
## Environment normalisation:
|
40
|
+
/.bundle/
|
41
|
+
/lib/bundler/man/
|
42
|
+
|
43
|
+
# for a library or gem, you might want to ignore these files since the code is
|
44
|
+
# intended to run in multiple environments; otherwise, check them in:
|
45
|
+
# Gemfile.lock
|
46
|
+
# .ruby-version
|
47
|
+
# .ruby-gemset
|
48
|
+
|
49
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
50
|
+
.rvmrc
|
51
|
+
>>>>>>> 62c17ee30b1a7d25ef12fab39fd6c2de0bcbadbc
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour --format documentation
|
data/.travis.yml
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- 1.9.3
|
4
|
+
- 2.0
|
5
|
+
- 2.1
|
6
|
+
- 2.2
|
7
|
+
- jruby
|
8
|
+
- rbx-2
|
9
|
+
matrix:
|
10
|
+
allow_failures:
|
11
|
+
- rvm: rbx-2
|
12
|
+
addons:
|
13
|
+
code_climate:
|
14
|
+
repo_token: 151a667c2c51ff76ac825c07c33e8e63c1ae9956a73f4d0ec7a043d877d05c95
|
15
|
+
notifications:
|
16
|
+
slack:
|
17
|
+
secure: Ykcz/gLRZcXhyOGedVgj1u3CDUbZS4y/nL1dREBE0Ar73Vrz+ulcMhri3VzfVBQGkWw06EjqHcIwsIomEInLJKxk3RTfpcYQAdYN+5iEDNOri9a5NK618WdrCuaCS3sKqYbJ/KB0slJDcJ1W+EXkr4GRqZTr5rPdmllUnoaqDCQ=
|
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--markup markdown --title "DKIM::Query Documentation" --protected
|
data/ChangeLog.md
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in dkim-query.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
group :development do
|
7
|
+
gem 'rake'
|
8
|
+
gem 'rspec', '~> 3.0'
|
9
|
+
|
10
|
+
gem 'kramdown'
|
11
|
+
gem 'yard', '~> 0.8'
|
12
|
+
end
|
13
|
+
|
14
|
+
group :test do
|
15
|
+
gem 'json'
|
16
|
+
gem 'codeclimate-test-reporter', require: nil
|
17
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 Trail of Bits
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
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, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
# dkim-query
|
2
|
+
|
3
|
+
[![Code Climate](https://codeclimate.com/github/trailofbits/dkim-query/badges/gpa.svg)](https://codeclimate.com/github/trailofbits/dkim-query)
|
4
|
+
[![Test Coverage](https://codeclimate.com/github/trailofbits/dkim-query/badges/coverage.svg)](https://codeclimate.com/github/trailofbits/dkim-query)
|
5
|
+
[![Build Status](https://travis-ci.org/trailofbits/dkim-query.svg)](https://travis-ci.org/trailofbits/dkim-query)
|
6
|
+
|
7
|
+
The `dkim-query` library searches the [DKIM] records for a host. We assume the
|
8
|
+
host uses standard dkim 'selectors', and also check if they use their own
|
9
|
+
'selector'.
|
10
|
+
|
11
|
+
## Examples
|
12
|
+
|
13
|
+
Parse a DKIM record:
|
14
|
+
|
15
|
+
require 'dkim/query'
|
16
|
+
|
17
|
+
key = DKIM::Query::Key.parse("k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDrEee0Ri4Juz+QfiWYui/E9UGSXau/2P8LjnTD8V4Unn+2FAZVGE3kL23bzeoULYv4PeleB3gfmJiDJOKU3Ns5L4KJAUUHjFwDebt0NP+sBK0VKeTATL2Yr/S3bT/xhy+1xtj4RkdV7fVxTn56Lb4udUnwuxK4V5b5PdOKj/+XcwIDAQAB; n=A 1024 bit key")
|
18
|
+
|
19
|
+
key.v
|
20
|
+
# => nil
|
21
|
+
|
22
|
+
key.g
|
23
|
+
# => nil
|
24
|
+
|
25
|
+
key.h
|
26
|
+
# => nil
|
27
|
+
|
28
|
+
key.k
|
29
|
+
# => :rsa
|
30
|
+
|
31
|
+
key.n
|
32
|
+
# => "A 1024 bit key"@230
|
33
|
+
|
34
|
+
key.p
|
35
|
+
# => "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDrEee0Ri4Juz+QfiWYui/E9UGSXau/2P8LjnTD8V4Unn+2FAZVGE3kL23bzeoULYv4PeleB3gfmJiDJOKU3Ns5L4KJAUUHjFwDebt0NP+sBK0VKeTATL2Yr/S3bT/xhy+1xtj4RkdV7fVxTn56Lb4udUnwuxK4V5b5PdOKj/+XcwIDAQAB"@10
|
36
|
+
|
37
|
+
key.s
|
38
|
+
# => nil
|
39
|
+
|
40
|
+
key.t
|
41
|
+
# => nil
|
42
|
+
|
43
|
+
Query all keys for a domain:
|
44
|
+
|
45
|
+
DKIM::Query::Domain.query('yahoo.com')
|
46
|
+
# => #<DKIM::Query::Domain:0x0000000315c950 @name="yahoo.com", @keys={"s1024"=>#<DKIM::Query::Key:0x0000000315c9f0 @v=nil, @g=nil, @h=nil, @k=:rsa, @n="A 1024 bit key;"@230, @p="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDrEee0Ri4Juz+QfiWYui/E9UGSXau/2P8LjnTD8V4Unn+2FAZVGE3kL23bzeoULYv4PeleB3gfmJiDJOKU3Ns5L4KJAUUHjFwDebt0NP+sBK0VKeTATL2Yr/S3bT/xhy+1xtj4RkdV7fVxTn56Lb4udUnwuxK4V5b5PdOKj/+XcwIDAQAB"@10, @s=nil, @t=nil>}>
|
47
|
+
|
48
|
+
## Synopsis
|
49
|
+
|
50
|
+
Query a domain:
|
51
|
+
|
52
|
+
dkim-query google.com
|
53
|
+
____________________________
|
54
|
+
DKIM record search for google.com
|
55
|
+
- using selectors: ["default", "dkim", "google"]
|
56
|
+
- no DKIM record found for google.com
|
57
|
+
____________________________
|
58
|
+
|
59
|
+
|
60
|
+
Query multiple domains:
|
61
|
+
|
62
|
+
dkim-query trailofbits.com facebook.com yahoo.com
|
63
|
+
____________________________
|
64
|
+
DKIM record search for trailofbits.com
|
65
|
+
- using selectors: ["default", "dkim", "google", "trailofbits"]
|
66
|
+
- found DKIM record for trailofbits.com at trailofbits._domainkey.trailofbits.com:
|
67
|
+
v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwe04g1hSR55ACcRiLAg0MoEiY5BBviJHJHq/d9r6o+F50fa1TrNNulwKXaST+WCEcW6D2KZ+dt9JvgB9ApIEAFCzHRXhawga0GsfDkOllvpXgT95IPcnYrSkM+rJSbaqHh+YI5sV9sKnvzZDVmB7l5gU3yD74aDmjs9wSg8RC5wIDAQAB
|
68
|
+
____________________________
|
69
|
+
|
70
|
+
____________________________
|
71
|
+
DKIM record search for facebook.com
|
72
|
+
- using selectors: ["default", "dkim", "google", "facebook"]
|
73
|
+
- found DKIM record for facebook.com at default._domainkey.facebook.com:
|
74
|
+
t=y; k=rsa; p=MHwwDQYJKoZIhvcNAQEBBQADawAwaAJhALkZ4wTn2SQ3EW0vVBExi8izmZZnjZH8JIY5Y964jzDORZku43o6ooFq6HLMjBxmcDYOrJFRdcsKDWtI0Be/uLfc/rClXuyEbcENXfadg77HHv35BI85RNy4TKeai3hxoQIDAQAB;
|
75
|
+
____________________________
|
76
|
+
|
77
|
+
____________________________
|
78
|
+
DKIM record search for yahoo.com
|
79
|
+
- using selectors: ["default", "dkim", "google", "yahoo"]
|
80
|
+
- no DKIM record found for yahoo.com
|
81
|
+
____________________________
|
82
|
+
|
83
|
+
## Requirements
|
84
|
+
|
85
|
+
* [ruby] >= 1.9.1
|
86
|
+
* [parslet] ~> 1.6
|
87
|
+
|
88
|
+
## Install
|
89
|
+
|
90
|
+
rake install
|
91
|
+
|
92
|
+
## License
|
93
|
+
|
94
|
+
See the {file:LICENSE.txt} file.
|
95
|
+
|
96
|
+
[DKIM]: https://tools.ietf.org/html/rfc6376
|
97
|
+
[ruby]: https://www.ruby-lang.org/
|
98
|
+
[parslet]: http://kschiess.github.io/parslet/
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'rubygems'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'bundler/setup'
|
6
|
+
rescue LoadError => e
|
7
|
+
warn e.message
|
8
|
+
warn "Run `gem install bundler` to install Bundler."
|
9
|
+
exit -1
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'rake'
|
13
|
+
require 'bundler/gem_tasks'
|
14
|
+
|
15
|
+
require 'rspec/core/rake_task'
|
16
|
+
RSpec::Core::RakeTask.new
|
17
|
+
|
18
|
+
task :test => :spec
|
19
|
+
task :default => :spec
|
20
|
+
|
21
|
+
require 'yard'
|
22
|
+
YARD::Rake::YardocTask.new
|
23
|
+
task :doc => :yard
|
data/bin/dkim-query
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
lib_dir = File.expand_path('../../lib',__FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
|
5
|
+
|
6
|
+
require 'dkim-query'
|
7
|
+
|
8
|
+
unless ARGV[0]
|
9
|
+
warn "Please supply at least one host name"
|
10
|
+
exit
|
11
|
+
end
|
12
|
+
|
13
|
+
ARGV.each do |arg|
|
14
|
+
puts "____________________________\n"
|
15
|
+
puts "DKIM record search for #{arg}"
|
16
|
+
|
17
|
+
domain = DKIM::Query::Domain.query(arg)
|
18
|
+
|
19
|
+
unless domain.keys.empty?
|
20
|
+
puts "- found DKIM record for #{arg}"
|
21
|
+
|
22
|
+
domain.keys.each do |selector,key|
|
23
|
+
puts " #{selector}:"
|
24
|
+
|
25
|
+
[:v, :g, :h, :k, :n, :p, :s, :t].each do |field|
|
26
|
+
value = key.send(field)
|
27
|
+
puts " #{field}: #{value}" if value
|
28
|
+
end
|
29
|
+
end
|
30
|
+
else
|
31
|
+
puts "- no DKIM record found for #{arg}"
|
32
|
+
end
|
33
|
+
puts "____________________________\n\n"
|
34
|
+
end
|
data/dkim-query.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'dkim/query/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "dkim-query"
|
8
|
+
gem.version = DKIM::Query::VERSION
|
9
|
+
gem.authors = ["nicktitle"]
|
10
|
+
gem.email = ["nick.esposito@trailofbits.com"]
|
11
|
+
gem.summary = %q{DKIM Retriever and Parser}
|
12
|
+
gem.description = %q{Search and retrieve DKIM records for any number of hosts}
|
13
|
+
gem.homepage = "https://github.com/trailofbits/dkim-query#readme"
|
14
|
+
gem.license = "MIT"
|
15
|
+
|
16
|
+
gem.files = `git ls-files -z`.split("\x0")
|
17
|
+
gem.executables = ['dkim-query']
|
18
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
|
+
gem.require_paths = ["lib"]
|
20
|
+
gem.required_ruby_version = '>= 1.9.1'
|
21
|
+
|
22
|
+
gem.add_dependency "parslet", "~> 1.6"
|
23
|
+
|
24
|
+
gem.add_development_dependency "bundler", "~> 1.6"
|
25
|
+
gem.add_development_dependency "rake", "~> 10.0"
|
26
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require 'dkim/query/query'
|
2
|
+
require 'dkim/query/key'
|
3
|
+
|
4
|
+
require 'resolv'
|
5
|
+
|
6
|
+
module DKIM
|
7
|
+
module Query
|
8
|
+
class Domain
|
9
|
+
|
10
|
+
include Enumerable
|
11
|
+
|
12
|
+
# Name of the domain
|
13
|
+
#
|
14
|
+
# @return [String]
|
15
|
+
attr_reader :name
|
16
|
+
|
17
|
+
# DKIM Keys of the domain
|
18
|
+
#
|
19
|
+
# @return [Hash{String => Key}]
|
20
|
+
attr_reader :keys
|
21
|
+
|
22
|
+
#
|
23
|
+
# Initializes the domain.
|
24
|
+
#
|
25
|
+
# @param [String] name
|
26
|
+
# The domain name.
|
27
|
+
#
|
28
|
+
# @param [Hash{String => Key}] keys
|
29
|
+
# The DKIM Keys of the domain.
|
30
|
+
#
|
31
|
+
# @api public
|
32
|
+
#
|
33
|
+
def initialize(name,keys={})
|
34
|
+
@name = name
|
35
|
+
@keys = keys
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
# Parses the DKIM Keys.
|
40
|
+
#
|
41
|
+
# @param [String] domain
|
42
|
+
# The domain the keys belong to.
|
43
|
+
#
|
44
|
+
# @param [Hash{String => String}] keys
|
45
|
+
# The DKIM selectors and keys.
|
46
|
+
#
|
47
|
+
# @return [Domain]
|
48
|
+
# The domain and it's parsed DKIM keys.
|
49
|
+
#
|
50
|
+
# @api semipublic
|
51
|
+
#
|
52
|
+
def self.parse(domain,keys={})
|
53
|
+
keys = Hash[keys.map { |selector,record|
|
54
|
+
[selector, Key.parse(record)]
|
55
|
+
}]
|
56
|
+
|
57
|
+
return new(domain,keys)
|
58
|
+
end
|
59
|
+
|
60
|
+
#
|
61
|
+
# Parses the DKIM Keys.
|
62
|
+
#
|
63
|
+
# @param [String] domain
|
64
|
+
# The domain the keys belong to.
|
65
|
+
#
|
66
|
+
# @param [Hash{String => String}] keys
|
67
|
+
# The DKIM selectors and keys.
|
68
|
+
#
|
69
|
+
# @return [Domain]
|
70
|
+
# The domain and it's parsed DKIM keys.
|
71
|
+
#
|
72
|
+
# @raise [Parslet::ParseFailed]
|
73
|
+
# One of the keys was invalid.
|
74
|
+
#
|
75
|
+
# @api semipublic
|
76
|
+
#
|
77
|
+
def self.parse!(domain,keys={})
|
78
|
+
keys = Hash[keys.map { |selector,record|
|
79
|
+
[selector, Key.parse!(record)]
|
80
|
+
}]
|
81
|
+
|
82
|
+
return new(domain,keys)
|
83
|
+
end
|
84
|
+
|
85
|
+
#
|
86
|
+
# Queries the domain for all DKIM selectors.
|
87
|
+
#
|
88
|
+
# @param [String] domain
|
89
|
+
# The domain to query.
|
90
|
+
#
|
91
|
+
# @option options [Array<String>] :selectors
|
92
|
+
# sub-domain selectors.
|
93
|
+
#
|
94
|
+
# @option options [Resolv::DNS] :resolver
|
95
|
+
#
|
96
|
+
# @return [Domain]
|
97
|
+
# The domain and it's DKIM Keys.
|
98
|
+
#
|
99
|
+
# @api public
|
100
|
+
#
|
101
|
+
def self.query(domain,options={})
|
102
|
+
parse(domain,Query.query(domain,options))
|
103
|
+
end
|
104
|
+
|
105
|
+
#
|
106
|
+
# Enumerates over each individual key.
|
107
|
+
#
|
108
|
+
# @yield [key]
|
109
|
+
# The given block will be passed each key.
|
110
|
+
#
|
111
|
+
# @yieldparam [DKIM::Query::Key] key
|
112
|
+
# A key belonging to the domain.
|
113
|
+
#
|
114
|
+
# @return [Enumerator]
|
115
|
+
# If no block was given, an Enumerator will be returned.
|
116
|
+
#
|
117
|
+
# @api public
|
118
|
+
#
|
119
|
+
def each(&block)
|
120
|
+
@keys.each_value(&block)
|
121
|
+
end
|
122
|
+
|
123
|
+
#
|
124
|
+
# Selects a key from the domain.
|
125
|
+
#
|
126
|
+
# @param [String] selector
|
127
|
+
# The selector.
|
128
|
+
#
|
129
|
+
# @return [Key, nil]
|
130
|
+
# The key within that selector.
|
131
|
+
#
|
132
|
+
def [](selector)
|
133
|
+
@keys[selector]
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require 'dkim/query/exceptions'
|
2
|
+
require 'dkim/query/parser'
|
3
|
+
require 'dkim/query/malformed_key'
|
4
|
+
|
5
|
+
module DKIM
|
6
|
+
module Query
|
7
|
+
class Key
|
8
|
+
|
9
|
+
attr_reader :v
|
10
|
+
alias version v
|
11
|
+
|
12
|
+
attr_reader :g
|
13
|
+
alias granularity g
|
14
|
+
|
15
|
+
attr_reader :h
|
16
|
+
alias hash h
|
17
|
+
|
18
|
+
attr_reader :k
|
19
|
+
alias key k
|
20
|
+
|
21
|
+
attr_reader :n
|
22
|
+
alias notes n
|
23
|
+
|
24
|
+
attr_reader :p
|
25
|
+
alias public_key p
|
26
|
+
|
27
|
+
attr_reader :s
|
28
|
+
alias service_type s
|
29
|
+
|
30
|
+
attr_reader :t
|
31
|
+
alias flags t
|
32
|
+
|
33
|
+
#
|
34
|
+
# Initialize the key.
|
35
|
+
#
|
36
|
+
# @param [Hash{Symbol => Symbol,String}] tags
|
37
|
+
# Tags for the key.
|
38
|
+
#
|
39
|
+
# @option tags [Symbol] :v
|
40
|
+
#
|
41
|
+
# @option tags [Symbol] :g
|
42
|
+
#
|
43
|
+
# @option tags [Symbol] :h
|
44
|
+
#
|
45
|
+
# @option tags [Symbol] :k
|
46
|
+
#
|
47
|
+
# @option tags [Symbol] :n
|
48
|
+
#
|
49
|
+
# @option tags [Symbol] :p
|
50
|
+
#
|
51
|
+
# @option tags [Symbol] :s
|
52
|
+
#
|
53
|
+
# @option tags [Symbol] :t
|
54
|
+
#
|
55
|
+
def initialize(tags={})
|
56
|
+
@v, @g, @h, @k, @n, @p, @s, @t = tags.values_at(:v,:g,:h,:k,:n,:p,:s,:t)
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# Parses a DKIM Key record.
|
61
|
+
#
|
62
|
+
# @param [String] record
|
63
|
+
# The DKIM key record.
|
64
|
+
#
|
65
|
+
# @return [Key]
|
66
|
+
# The new key.
|
67
|
+
#
|
68
|
+
# @raise [InvalidKey]
|
69
|
+
# Could not parse the DKIM Key record.
|
70
|
+
#
|
71
|
+
def self.parse!(record)
|
72
|
+
new(Parser.parse(record))
|
73
|
+
rescue Parslet::ParseFailed => error
|
74
|
+
raise(InvalidKey.new(error.message,error.cause))
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# Parses a DKIM Key record.
|
79
|
+
#
|
80
|
+
# @param [String] record
|
81
|
+
# The DKIM key record.
|
82
|
+
#
|
83
|
+
# @return [Key, MalformedKey]
|
84
|
+
# The parsed key. If the key could not be parsed, a {MalformedKey}
|
85
|
+
# will be returned.
|
86
|
+
#
|
87
|
+
def self.parse(record)
|
88
|
+
begin
|
89
|
+
parse!(record)
|
90
|
+
rescue Parslet::ParseFailed => error
|
91
|
+
MalformedKey.new(record,error.cause)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
#
|
96
|
+
# Converts the key to a Hash.
|
97
|
+
#
|
98
|
+
# @return [Hash{:v,:g,:h,:k,:n,:p,:s,:t => Object}]
|
99
|
+
#
|
100
|
+
def to_hash
|
101
|
+
{
|
102
|
+
v: @v,
|
103
|
+
g: @g,
|
104
|
+
h: @h,
|
105
|
+
k: @k,
|
106
|
+
n: @n,
|
107
|
+
p: @p,
|
108
|
+
s: @s,
|
109
|
+
t: @t
|
110
|
+
}
|
111
|
+
end
|
112
|
+
|
113
|
+
#
|
114
|
+
# Converts the key back into a DKIM String.
|
115
|
+
#
|
116
|
+
# @return [String]
|
117
|
+
#
|
118
|
+
def to_s
|
119
|
+
tags = []
|
120
|
+
|
121
|
+
tags << "v=#{@v}" if @v
|
122
|
+
tags << "g=#{@g}" if @g
|
123
|
+
tags << "h=#{@h}" if @h
|
124
|
+
tags << "k=#{@k}" if @k
|
125
|
+
tags << "p=#{@p}" if @p
|
126
|
+
tags << "s=#{@s}" if @s
|
127
|
+
tags << "t=#{@t}" if @t
|
128
|
+
tags << "n=#{@n}" if @n
|
129
|
+
|
130
|
+
return tags.join('; ')
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module DKIM
|
2
|
+
module Query
|
3
|
+
class MalformedKey
|
4
|
+
|
5
|
+
# Raw value of the DKIM key.
|
6
|
+
#
|
7
|
+
# @return [String]
|
8
|
+
attr_reader :value
|
9
|
+
|
10
|
+
# Cause of the parser failure.
|
11
|
+
#
|
12
|
+
# @return [Parslet::Cause]
|
13
|
+
attr_reader :cause
|
14
|
+
|
15
|
+
#
|
16
|
+
# Initializes the malformed key.
|
17
|
+
#
|
18
|
+
# @param [String] value
|
19
|
+
# The raw DKIM key.
|
20
|
+
#
|
21
|
+
# @param [Parslet::Cause] cause
|
22
|
+
# The cause of the parser failure.
|
23
|
+
#
|
24
|
+
def initialize(value,cause)
|
25
|
+
@value = value
|
26
|
+
@cause = cause
|
27
|
+
end
|
28
|
+
|
29
|
+
alias value to_s
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|