dmarcurator 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/LICENSE +20 -0
- data/README.md +21 -0
- data/Rakefile +1 -0
- data/bin/dmarcurator +4 -0
- data/dmarcurator.gemspec +22 -0
- data/lib/dmarcurator/cli/app.rb +65 -0
- data/lib/dmarcurator/import_reports.rb +25 -0
- data/lib/dmarcurator/parser/base.rb +23 -0
- data/lib/dmarcurator/parser/record.rb +55 -0
- data/lib/dmarcurator/parser/report.rb +65 -0
- data/lib/dmarcurator/parser.rb +7 -0
- data/lib/dmarcurator/store/record.rb +42 -0
- data/lib/dmarcurator/store/report.rb +52 -0
- data/lib/dmarcurator/store.rb +7 -0
- data/lib/dmarcurator/version.rb +5 -0
- data/lib/dmarcurator.rb +14 -0
- metadata +148 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4db33b8efc1496dabb33d6612b082a56c47a1b28
|
4
|
+
data.tar.gz: 0a60be2fbc7fcc09ae27c6d4fcee25cbd1eb0fd9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 25fd8f9c7898fc133c58b27645921e01ab085a8a86dc319618ddd110cee1f555ceee3067b01fd5c9436c4d53fae0d726a07acabd1e6d44c06519be99848cae2e
|
7
|
+
data.tar.gz: 908dc64c6d499f5e37e5068c1cc5270154ea7114e83b1ca2c10d226809232cfe3ca4cabfa21bce1590c56731af7411bf7548751b78489352d056643c9333f395
|
data/.gitignore
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.3.1
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Ayumi Yu
|
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,21 @@
|
|
1
|
+
## dmarcurator
|
2
|
+
|
3
|
+
Imports DMARC report XML into SQLite DB.
|
4
|
+
|
5
|
+
- [More info on email authentication](https://jl.ly/Email/authcheat.html)
|
6
|
+
|
7
|
+
## install
|
8
|
+
|
9
|
+
Install sqlite3 bc it's cool and you need it
|
10
|
+
`brew install sqlite3`
|
11
|
+
|
12
|
+
`gem install dmarcurator`
|
13
|
+
|
14
|
+
## usage
|
15
|
+
|
16
|
+
- Get some DMARC reports in XML and put them in a directory.
|
17
|
+
- `dmarcurator --db=./dmarc/reports.sqlite --reports-path=./dmarc/reports`
|
18
|
+
|
19
|
+
## how to browse db
|
20
|
+
|
21
|
+
[SQLite-web](https://github.com/coleifer/sqlite-web) is a deec interface.
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/dmarcurator
ADDED
data/dmarcurator.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require File.expand_path("../lib/dmarcurator/version", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.add_dependency "ox", "~> 2.4"
|
6
|
+
s.add_dependency "sequel", "~> 4.38"
|
7
|
+
s.add_dependency "sqlite3", "~> 1.3"
|
8
|
+
s.add_development_dependency "bundler", "~> 1.13"
|
9
|
+
s.add_development_dependency "pry", "~> 0"
|
10
|
+
s.add_development_dependency "rake", "~> 0"
|
11
|
+
s.authors = ["Ayumi Yu"]
|
12
|
+
s.description = "Simple tool for viewing DMARC reports"
|
13
|
+
s.email = ["ayumi@ayumiyu.com"]
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
16
|
+
s.homepage = "https://github.com/ayumi/dmarcurator"
|
17
|
+
s.license = "MIT"
|
18
|
+
s.name = "dmarcurator"
|
19
|
+
s.summary = "Tool for viewing DMARC reports"
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
s.version = Dmarcurator::VERSION
|
22
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Dmarcurator
|
3
|
+
module Cli
|
4
|
+
class App
|
5
|
+
require "pry"
|
6
|
+
|
7
|
+
attr_reader :db_uri, :reports_path
|
8
|
+
|
9
|
+
def self.main
|
10
|
+
params = parse_options(ARGV)
|
11
|
+
new(params).run
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.parse_options(options)
|
15
|
+
params = {}
|
16
|
+
|
17
|
+
opt_parser = OptionParser.new do |parser|
|
18
|
+
parser.banner = "dmarcurator parses DMARC reports and stores them into an SQLite3 DB.\nIt can also serve a basic web UI for viewing reports (-ui=true).\nUsage: dmarcurator [options]"
|
19
|
+
|
20
|
+
parser.on("-db", "--db-sqlite=SQLITE_DB", "[Required] Path to sqlite3 DB. (e.g. ./tmp/reports.sqlite)") do |value|
|
21
|
+
params[:db_path] = value
|
22
|
+
end
|
23
|
+
|
24
|
+
parser.on("-rp", "--reports-path=REPORTS_PATH", "Path to directory containing DMARC reports. (e.g. ./tmp/reports/)") do |value|
|
25
|
+
params[:reports_path] = value
|
26
|
+
end
|
27
|
+
|
28
|
+
parser.on("-h", "--help", "Halp pls") do
|
29
|
+
puts parser
|
30
|
+
exit 0
|
31
|
+
end
|
32
|
+
|
33
|
+
parser.on("-v", "--version", "Print version") do
|
34
|
+
puts ::Dmarcurator::VERSION
|
35
|
+
exit 0
|
36
|
+
end
|
37
|
+
|
38
|
+
if options.empty?
|
39
|
+
puts parser
|
40
|
+
exit 1
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
opt_parser.parse!(options)
|
45
|
+
if !params[:reports_path]
|
46
|
+
puts "Dmarcurator can import DMARC reports into an sqlite3 database -> Set --db and --reports-path)"
|
47
|
+
exit 0
|
48
|
+
end
|
49
|
+
|
50
|
+
params
|
51
|
+
end
|
52
|
+
|
53
|
+
def initialize(db_path:, reports_path: nil)
|
54
|
+
@db_uri = "sqlite://#{File.expand_path(db_path)}"
|
55
|
+
@reports_path = reports_path
|
56
|
+
end
|
57
|
+
|
58
|
+
def run
|
59
|
+
if reports_path
|
60
|
+
::Dmarcurator::ImportReports.new(db_uri: db_uri, reports_path: reports_path).run
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "sequel"
|
3
|
+
|
4
|
+
module Dmarcurator
|
5
|
+
# Import DMARC XML reports into DB
|
6
|
+
class ImportReports
|
7
|
+
attr_reader :db, :reports_path
|
8
|
+
|
9
|
+
def initialize(db_uri:, reports_path:)
|
10
|
+
@db = Sequel.connect(db_uri)
|
11
|
+
@reports_path = reports_path
|
12
|
+
end
|
13
|
+
|
14
|
+
def run
|
15
|
+
puts "Importing #{reports_path}"
|
16
|
+
Dir.foreach(reports_path) do |path|
|
17
|
+
next if path == '.' || path == '..' || File.extname(path) != ".xml"
|
18
|
+
puts " #{path}"
|
19
|
+
parsed_report = ::Dmarcurator::Parser::Report.new(xml: "#{reports_path}/#{path}")
|
20
|
+
::Dmarcurator::Store::Report.import_parsed(db: db, parsed: parsed_report)
|
21
|
+
end
|
22
|
+
puts "Done importing :)"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "open3"
|
3
|
+
require "ox"
|
4
|
+
|
5
|
+
module Dmarcurator
|
6
|
+
module Parser
|
7
|
+
# Base XML parser
|
8
|
+
class Base
|
9
|
+
attr_reader :doc
|
10
|
+
|
11
|
+
def initialize(xml: nil, parsed_xml: nil)
|
12
|
+
if xml
|
13
|
+
content = File.read(xml)
|
14
|
+
@doc = Ox.parse(content)
|
15
|
+
elsif parsed_xml
|
16
|
+
@doc = parsed_xml
|
17
|
+
else
|
18
|
+
raise "Either :xml or :parsed_xml are required"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Dmarcurator
|
3
|
+
module Parser
|
4
|
+
# Parsed XML of a record
|
5
|
+
class Record < Base
|
6
|
+
def source_ip
|
7
|
+
doc.locate("row/source_ip")[0].text
|
8
|
+
end
|
9
|
+
|
10
|
+
def count
|
11
|
+
doc.locate("row/count")[0].text.to_i
|
12
|
+
end
|
13
|
+
|
14
|
+
def disposition
|
15
|
+
doc.locate("row/policy_evaluated/disposition")[0].text
|
16
|
+
end
|
17
|
+
|
18
|
+
def policy_result_dkim
|
19
|
+
doc.locate("row/policy_evaluated/dkim")[0].text
|
20
|
+
end
|
21
|
+
|
22
|
+
def policy_result_spf
|
23
|
+
doc.locate("row/policy_evaluated/spf")[0].text
|
24
|
+
end
|
25
|
+
|
26
|
+
def envelope_to
|
27
|
+
doc.locate("identifiers/envelope_to")[0]&.text
|
28
|
+
end
|
29
|
+
|
30
|
+
def header_from
|
31
|
+
doc.locate("identifiers/header_from")[0].text
|
32
|
+
end
|
33
|
+
|
34
|
+
def auth_dkim_domain
|
35
|
+
doc.locate("auth_results/dkim/domain")[0]&.text
|
36
|
+
end
|
37
|
+
|
38
|
+
def auth_dkim_result
|
39
|
+
doc.locate("auth_results/dkim/result")[0]&.text
|
40
|
+
end
|
41
|
+
|
42
|
+
def auth_dkim_selector
|
43
|
+
doc.locate("auth_results/dkim/selector")[0]&.text
|
44
|
+
end
|
45
|
+
|
46
|
+
def auth_spf_domain
|
47
|
+
doc.locate("auth_results/spf/domain")[0].text
|
48
|
+
end
|
49
|
+
|
50
|
+
def auth_spf_result
|
51
|
+
doc.locate("auth_results/spf/result")[0].text
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Dmarcurator
|
3
|
+
module Parser
|
4
|
+
# Parsed XML of a report
|
5
|
+
class Report < Base
|
6
|
+
def org_name
|
7
|
+
doc.locate("feedback/report_metadata/org_name")[0].text
|
8
|
+
end
|
9
|
+
|
10
|
+
def email
|
11
|
+
doc.locate("feedback/report_metadata/email")[0].text
|
12
|
+
end
|
13
|
+
|
14
|
+
def extra_contact_info
|
15
|
+
doc.locate("feedback/report_metadata/extra_contact_info")[0]&.text
|
16
|
+
end
|
17
|
+
|
18
|
+
def dmarc_report_id
|
19
|
+
doc.locate("feedback/report_metadata/report_id")[0].text
|
20
|
+
end
|
21
|
+
|
22
|
+
def error
|
23
|
+
doc.locate("feedback/report_metadata/error")[0]&.text
|
24
|
+
end
|
25
|
+
|
26
|
+
def begin_at
|
27
|
+
Time.at(doc.locate("feedback/report_metadata/date_range/begin")[0].text.to_i)
|
28
|
+
end
|
29
|
+
|
30
|
+
def end_at
|
31
|
+
Time.at(doc.locate("feedback/report_metadata/date_range/end")[0].text.to_i)
|
32
|
+
end
|
33
|
+
|
34
|
+
def policy_domain
|
35
|
+
doc.locate("feedback/policy_published/domain")[0].text
|
36
|
+
end
|
37
|
+
|
38
|
+
def policy_adkim
|
39
|
+
doc.locate("feedback/policy_published/adkim")[0]&.text
|
40
|
+
end
|
41
|
+
|
42
|
+
def policy_aspf
|
43
|
+
doc.locate("feedback/policy_published/aspf")[0]&.text
|
44
|
+
end
|
45
|
+
|
46
|
+
def policy_p
|
47
|
+
doc.locate("feedback/policy_published/p")[0].text
|
48
|
+
end
|
49
|
+
|
50
|
+
def policy_sp
|
51
|
+
doc.locate("feedback/policy_published/sp")[0]&.text
|
52
|
+
end
|
53
|
+
|
54
|
+
def policy_pct
|
55
|
+
doc.locate("feedback/policy_published/pct")[0].text.to_i
|
56
|
+
end
|
57
|
+
|
58
|
+
def records
|
59
|
+
doc.locate("feedback/record").map do |record|
|
60
|
+
Record.new(parsed_xml: record)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "sequel"
|
3
|
+
|
4
|
+
module Dmarcurator
|
5
|
+
class Store
|
6
|
+
# DMARC report. Contains many records.
|
7
|
+
class Record
|
8
|
+
attr_reader :db
|
9
|
+
|
10
|
+
def self.create_table(db:)
|
11
|
+
db.create_table :records do
|
12
|
+
primary_key :id
|
13
|
+
foreign_key(:report_id, :reports, key: :id)
|
14
|
+
String :source_ip
|
15
|
+
Integer :count
|
16
|
+
String :disposition
|
17
|
+
String :policy_result_dkim
|
18
|
+
String :policy_result_spf
|
19
|
+
String :envelope_to
|
20
|
+
String :header_from
|
21
|
+
String :auth_dkim_domain
|
22
|
+
String :auth_dkim_result
|
23
|
+
String :auth_dkim_selector
|
24
|
+
String :auth_spf_domain
|
25
|
+
String :auth_spf_result
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.import_parsed(db:, parsed:, report_id:)
|
30
|
+
create_table(db: db) if !db.table_exists?(:records)
|
31
|
+
|
32
|
+
attributes = { report_id: report_id }
|
33
|
+
db[:records].columns.each do |attribute|
|
34
|
+
next if !parsed.respond_to?(attribute)
|
35
|
+
attributes[attribute] = parsed.public_send(attribute)
|
36
|
+
end
|
37
|
+
result = db[:records].insert(attributes)
|
38
|
+
STDOUT << "."
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# DMARC report. Contains many records.
|
3
|
+
module Dmarcurator
|
4
|
+
class Store
|
5
|
+
class Report
|
6
|
+
attr_reader :db
|
7
|
+
|
8
|
+
def self.create_table(db:)
|
9
|
+
puts "Creating table: reports"
|
10
|
+
db.create_table :reports do
|
11
|
+
primary_key :id
|
12
|
+
String :org_name
|
13
|
+
String :email
|
14
|
+
String :extra_contact_info
|
15
|
+
String :dmarc_report_id
|
16
|
+
String :error
|
17
|
+
DateTime :begin_at
|
18
|
+
DateTime :end_at
|
19
|
+
String :policy_domain
|
20
|
+
String :policy_adkim
|
21
|
+
String :policy_aspf
|
22
|
+
String :policy_p
|
23
|
+
String :policy_sp
|
24
|
+
Integer :policy_pct
|
25
|
+
|
26
|
+
index :dmarc_report_id
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.import_parsed(db:, parsed:)
|
31
|
+
create_table(db: db) if !db.table_exists?(:reports)
|
32
|
+
if db[:reports].where(dmarc_report_id: parsed.dmarc_report_id).count > 0
|
33
|
+
puts "Report exists; skipping"
|
34
|
+
return
|
35
|
+
end
|
36
|
+
|
37
|
+
attributes = {}
|
38
|
+
db[:reports].columns.each do |attribute|
|
39
|
+
next if !parsed.respond_to?(attribute)
|
40
|
+
attributes[attribute] = parsed.public_send(attribute)
|
41
|
+
end
|
42
|
+
result = db[:reports].insert(attributes)
|
43
|
+
imported_report_id = db[:reports].select(:id).order('id ASC').limit(1).first[:id]
|
44
|
+
|
45
|
+
parsed.records.each do |parsed_record|
|
46
|
+
Record.import_parsed(db: db, parsed: parsed_record, report_id: imported_report_id)
|
47
|
+
end
|
48
|
+
puts "Report++"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/dmarcurator.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "dmarcurator/version"
|
3
|
+
|
4
|
+
module Dmarcurator
|
5
|
+
require "dmarcurator/cli/app"
|
6
|
+
require "dmarcurator/import_reports"
|
7
|
+
require "dmarcurator/parser"
|
8
|
+
require "dmarcurator/parser/base"
|
9
|
+
require "dmarcurator/parser/record"
|
10
|
+
require "dmarcurator/parser/report"
|
11
|
+
require "dmarcurator/store"
|
12
|
+
require "dmarcurator/store/record"
|
13
|
+
require "dmarcurator/store/report"
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dmarcurator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ayumi Yu
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-09-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ox
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.4'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.4'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sequel
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4.38'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '4.38'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sqlite3
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.3'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.13'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.13'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: Simple tool for viewing DMARC reports
|
98
|
+
email:
|
99
|
+
- ayumi@ayumiyu.com
|
100
|
+
executables:
|
101
|
+
- dmarcurator
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- ".gitignore"
|
106
|
+
- ".ruby-version"
|
107
|
+
- Gemfile
|
108
|
+
- LICENSE
|
109
|
+
- README.md
|
110
|
+
- Rakefile
|
111
|
+
- bin/dmarcurator
|
112
|
+
- dmarcurator.gemspec
|
113
|
+
- lib/dmarcurator.rb
|
114
|
+
- lib/dmarcurator/cli/app.rb
|
115
|
+
- lib/dmarcurator/import_reports.rb
|
116
|
+
- lib/dmarcurator/parser.rb
|
117
|
+
- lib/dmarcurator/parser/base.rb
|
118
|
+
- lib/dmarcurator/parser/record.rb
|
119
|
+
- lib/dmarcurator/parser/report.rb
|
120
|
+
- lib/dmarcurator/store.rb
|
121
|
+
- lib/dmarcurator/store/record.rb
|
122
|
+
- lib/dmarcurator/store/report.rb
|
123
|
+
- lib/dmarcurator/version.rb
|
124
|
+
homepage: https://github.com/ayumi/dmarcurator
|
125
|
+
licenses:
|
126
|
+
- MIT
|
127
|
+
metadata: {}
|
128
|
+
post_install_message:
|
129
|
+
rdoc_options: []
|
130
|
+
require_paths:
|
131
|
+
- lib
|
132
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - ">="
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
|
+
requirements:
|
139
|
+
- - ">="
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
requirements: []
|
143
|
+
rubyforge_project:
|
144
|
+
rubygems_version: 2.5.1
|
145
|
+
signing_key:
|
146
|
+
specification_version: 4
|
147
|
+
summary: Tool for viewing DMARC reports
|
148
|
+
test_files: []
|