passivedns-client 2.0.4 → 2.0.6
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 +4 -4
- data/README.md +1 -1
- data/lib/passivedns/client/cli.rb +33 -21
- data/lib/passivedns/client/version.rb +1 -1
- data/test/test_cli.rb +204 -0
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9fc3d708ad9c1dd55d73acf19b347589c8142292
|
4
|
+
data.tar.gz: f48765e8140f0f84dd26a8912728190458ab3dbb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c6d15bd3b5e0c556b515512be6645b626139f9c0c2c42c8e48bb7347599edb2bcbb6ca0b011dd8c981a2fdd2d13f50e98f1d34935f81223a60039c237531052
|
7
|
+
data.tar.gz: d14cf8d3a6e50d8e1708d4fa32d11655efec83403ca9ba62fd10c3246dac1b7930d59ace1245a1cd5079270d22fbe7eba3124897b0b6bd95c8518f6346c13e12
|
data/README.md
CHANGED
@@ -94,7 +94,7 @@ Or use the included tool...
|
|
94
94
|
|
95
95
|
Output Formatting
|
96
96
|
-g link-nodal GDF visualization definition
|
97
|
-
-
|
97
|
+
-z link-nodal graphviz visualization definition
|
98
98
|
-m link-nodal graphml visualization definition
|
99
99
|
-c CSV
|
100
100
|
-x XML
|
@@ -2,17 +2,30 @@ require 'getoptlong'
|
|
2
2
|
require 'structformatter'
|
3
3
|
require 'getoptlong'
|
4
4
|
require 'yaml'
|
5
|
+
require 'pp'
|
5
6
|
|
6
7
|
module PassiveDNS
|
7
8
|
class CLInterface
|
9
|
+
def self.get_letter_map
|
10
|
+
letter_map = {}
|
11
|
+
PassiveDNS.constants.each do |const|
|
12
|
+
if PassiveDNS.const_get(const).is_a?(Class) and PassiveDNS.const_get(const).superclass == PassiveDNS::PassiveDB
|
13
|
+
letter_map[PassiveDNS.const_get(const).option_letter] = [PassiveDNS.const_get(const).name, PassiveDNS.const_get(const).config_section_name]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
letter_map
|
17
|
+
end
|
18
|
+
|
8
19
|
def self.parse_command_line(args)
|
20
|
+
origARGV = ARGV.dup
|
21
|
+
ARGV.replace(args)
|
9
22
|
opts = GetoptLong.new(
|
10
23
|
[ '--help', '-h', GetoptLong::NO_ARGUMENT ],
|
11
|
-
[ '--debug', '-
|
24
|
+
[ '--debug', '-v', GetoptLong::NO_ARGUMENT ],
|
12
25
|
[ '--database', '-d', GetoptLong::REQUIRED_ARGUMENT ],
|
13
26
|
|
14
27
|
[ '--gdf', '-g', GetoptLong::NO_ARGUMENT ],
|
15
|
-
[ '--graphviz', '-
|
28
|
+
[ '--graphviz', '-z', GetoptLong::NO_ARGUMENT ],
|
16
29
|
[ '--graphml', '-m', GetoptLong::NO_ARGUMENT ],
|
17
30
|
[ '--csv', '-c', GetoptLong::NO_ARGUMENT ],
|
18
31
|
[ '--xml', '-x', GetoptLong::NO_ARGUMENT ],
|
@@ -27,12 +40,7 @@ module PassiveDNS
|
|
27
40
|
[ '--limit', '-l', GetoptLong::REQUIRED_ARGUMENT ]
|
28
41
|
)
|
29
42
|
|
30
|
-
letter_map =
|
31
|
-
PassiveDNS.constants.each do |const|
|
32
|
-
if PassiveDNS.const_get(const).is_a?(Class) and PassiveDNS.const_get(const).superclass == PassiveDNS::PassiveDB
|
33
|
-
letter_map[PassiveDNS.const_get(const).option_letter] = [PassiveDNS.const_get(const).name, PassiveDNS.const_get(const).config_section_name]
|
34
|
-
end
|
35
|
-
end
|
43
|
+
letter_map = get_letter_map
|
36
44
|
|
37
45
|
# sets the default search methods
|
38
46
|
options = {
|
@@ -44,14 +52,14 @@ module PassiveDNS
|
|
44
52
|
:res => nil,
|
45
53
|
:debug => false,
|
46
54
|
:sqlitedb => nil,
|
47
|
-
:limit => nil
|
55
|
+
:limit => nil,
|
56
|
+
:help => false
|
48
57
|
}
|
49
58
|
|
50
59
|
opts.each do |opt, arg|
|
51
60
|
case opt
|
52
61
|
when '--help'
|
53
|
-
|
54
|
-
exit
|
62
|
+
options[:help] = true
|
55
63
|
when '--debug'
|
56
64
|
options[:debug] = true
|
57
65
|
when '--database'
|
@@ -86,10 +94,6 @@ module PassiveDNS
|
|
86
94
|
options[:sep] = arg
|
87
95
|
when '--recurse'
|
88
96
|
options[:recursedepth] = arg.to_i
|
89
|
-
if options[:recursedepth] > 3
|
90
|
-
$stderr.puts "WARNING: a recursedepth of > 3 can be abusive, please reconsider: sleeping 60 seconds for sense to come to you (hint: hit CTRL-C)"
|
91
|
-
sleep 60
|
92
|
-
end
|
93
97
|
when '--wait'
|
94
98
|
options[:wait] = arg.to_i
|
95
99
|
when '--sqlite3'
|
@@ -97,10 +101,11 @@ module PassiveDNS
|
|
97
101
|
when '--limit'
|
98
102
|
options[:limit] = arg.to_i
|
99
103
|
else
|
100
|
-
|
101
|
-
exit
|
104
|
+
options[:help] = true
|
102
105
|
end
|
103
106
|
end
|
107
|
+
args = ARGV.dup
|
108
|
+
ARGV.replace(origARGV)
|
104
109
|
|
105
110
|
if options[:pdnsdbs].length == 0
|
106
111
|
options[:pdnsdbs] << "bfk"
|
@@ -129,9 +134,9 @@ module PassiveDNS
|
|
129
134
|
|
130
135
|
def self.usage(letter_map)
|
131
136
|
databases = letter_map.keys.sort.join("")
|
132
|
-
help_text = "
|
137
|
+
help_text = ""
|
133
138
|
help_text << "Usage: #{$0} [-d [#{databases}]] [-g|-v|-m|-c|-x|-y|-j|-t] [-os <sep>] [-f <file>] [-r#|-w#|-v] [-l <count>] <ip|domain|cidr>\n"
|
134
|
-
help_text << "Passive DNS Providers"
|
139
|
+
help_text << "Passive DNS Providers\n"
|
135
140
|
help_text << " -d#{databases} uses all of the available passive dns database\n"
|
136
141
|
letter_map.keys.sort.each do |l|
|
137
142
|
help_text << " -d#{l} use #{letter_map[l][0]}\n"
|
@@ -140,7 +145,7 @@ module PassiveDNS
|
|
140
145
|
help_text << "\n"
|
141
146
|
help_text << "Output Formatting\n"
|
142
147
|
help_text << " -g link-nodal GDF visualization definition\n"
|
143
|
-
help_text << " -
|
148
|
+
help_text << " -z link-nodal graphviz visualization definition\n"
|
144
149
|
help_text << " -m link-nodal graphml visualization definition\n"
|
145
150
|
help_text << " -c CSV\n"
|
146
151
|
help_text << " -x XML\n"
|
@@ -149,7 +154,7 @@ module PassiveDNS
|
|
149
154
|
help_text << " -t ASCII text (default)\n"
|
150
155
|
help_text << " -s <sep> specifies a field separator for text output, default is tab\n"
|
151
156
|
help_text << "\n"
|
152
|
-
help_text << "State and
|
157
|
+
help_text << "State and Recursion\n"
|
153
158
|
help_text << " -f[file] specifies a sqlite3 database used to read the current state - useful for large result sets and generating graphs of previous runs.\n"
|
154
159
|
help_text << " -r# specifies the levels of recursion to pull. **WARNING** This is quite taxing on the pDNS servers, so use judiciously (never more than 3 or so) or find yourself blocked!\n"
|
155
160
|
help_text << " -w# specifies the amount of time to wait, in seconds, between queries (Default: 0)\n"
|
@@ -222,6 +227,13 @@ module PassiveDNS
|
|
222
227
|
|
223
228
|
def self.run(args)
|
224
229
|
options, items = parse_command_line(args)
|
230
|
+
if options[:help]
|
231
|
+
return usage(get_letter_map)
|
232
|
+
end
|
233
|
+
if options[:recursedepth] > 3
|
234
|
+
$stderr.puts "WARNING: a recursedepth of > 3 can be abusive, please reconsider: sleeping 60 seconds for sense to come to you (hint: hit CTRL-C)"
|
235
|
+
sleep 60
|
236
|
+
end
|
225
237
|
state = create_state(options[:sqlitedb])
|
226
238
|
state.debug = options[:debug]
|
227
239
|
|
data/test/test_cli.rb
ADDED
@@ -0,0 +1,204 @@
|
|
1
|
+
unless Kernel.respond_to?(:require_relative)
|
2
|
+
module Kernel
|
3
|
+
def require_relative(path)
|
4
|
+
require File.join(File.dirname(caller[0]), path.to_str)
|
5
|
+
end
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
require_relative 'helper'
|
10
|
+
require 'configparser'
|
11
|
+
require_relative '../lib/passivedns/client/cli.rb'
|
12
|
+
|
13
|
+
class TestCLI < Minitest::Test
|
14
|
+
def test_letter_map
|
15
|
+
letter_map = PassiveDNS::CLI.get_letter_map
|
16
|
+
assert_equal("3bcdmptv", letter_map.keys.sort.join(""))
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_help_text
|
20
|
+
helptext = PassiveDNS::CLI.run(["--help"])
|
21
|
+
helptext.gsub!(/Usage: .*?\[/, "Usage: [")
|
22
|
+
assert_equal(
|
23
|
+
"Usage: [-d [3bcdmptv]] [-g|-v|-m|-c|-x|-y|-j|-t] [-os <sep>] [-f <file>] [-r#|-w#|-v] [-l <count>] <ip|domain|cidr>
|
24
|
+
Passive DNS Providers
|
25
|
+
-d3bcdmptv uses all of the available passive dns database
|
26
|
+
-d3 use 360.cn
|
27
|
+
-db use BFK.de
|
28
|
+
-dc use CIRCL
|
29
|
+
-dd use DNSDB
|
30
|
+
-dm use Mnemonic
|
31
|
+
-dp use PassiveTotal
|
32
|
+
-dt use TCPIPUtils
|
33
|
+
-dv use VirusTotal
|
34
|
+
-dvt uses VirusTotal and TCPIPUtils (for example)
|
35
|
+
|
36
|
+
Output Formatting
|
37
|
+
-g link-nodal GDF visualization definition
|
38
|
+
-z link-nodal graphviz visualization definition
|
39
|
+
-m link-nodal graphml visualization definition
|
40
|
+
-c CSV
|
41
|
+
-x XML
|
42
|
+
-y YAML
|
43
|
+
-j JSON
|
44
|
+
-t ASCII text (default)
|
45
|
+
-s <sep> specifies a field separator for text output, default is tab
|
46
|
+
|
47
|
+
State and Recursion
|
48
|
+
-f[file] specifies a sqlite3 database used to read the current state - useful for large result sets and generating graphs of previous runs.
|
49
|
+
-r# specifies the levels of recursion to pull. **WARNING** This is quite taxing on the pDNS servers, so use judiciously (never more than 3 or so) or find yourself blocked!
|
50
|
+
-w# specifies the amount of time to wait, in seconds, between queries (Default: 0)
|
51
|
+
-l <count> limits the number of records returned per passive dns database queried.
|
52
|
+
|
53
|
+
Getting Help
|
54
|
+
-h hello there. This option produces this helpful help information on how to access help.
|
55
|
+
-v debugging information
|
56
|
+
", helptext)
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_provider_parsing
|
60
|
+
options_target = {
|
61
|
+
:pdnsdbs => ["bfk"],
|
62
|
+
:format => "text",
|
63
|
+
:sep => "\t",
|
64
|
+
:recursedepth => 1,
|
65
|
+
:wait => 0,
|
66
|
+
:res => nil,
|
67
|
+
:debug => false,
|
68
|
+
:sqlitedb => nil,
|
69
|
+
:limit => nil,
|
70
|
+
:help => false
|
71
|
+
}
|
72
|
+
|
73
|
+
options, items = PassiveDNS::CLI.parse_command_line([])
|
74
|
+
assert_equal(options_target, options)
|
75
|
+
assert_equal([], items)
|
76
|
+
|
77
|
+
options_target[:pdnsdbs] = ["cn360"]
|
78
|
+
options, items = PassiveDNS::CLI.parse_command_line(["-d3"])
|
79
|
+
assert_equal(options_target, options)
|
80
|
+
assert_equal([], items)
|
81
|
+
|
82
|
+
options_target[:pdnsdbs] = ["bfk"]
|
83
|
+
options, items = PassiveDNS::CLI.parse_command_line(["-db"])
|
84
|
+
assert_equal(options_target, options)
|
85
|
+
assert_equal([], items)
|
86
|
+
|
87
|
+
options_target[:pdnsdbs] = ["circl", "dnsdb", "mnemonic"]
|
88
|
+
options, items = PassiveDNS::CLI.parse_command_line(["-dcdm"])
|
89
|
+
assert_equal(options_target, options)
|
90
|
+
assert_equal([], items)
|
91
|
+
|
92
|
+
options_target[:pdnsdbs] = ["passivetotal", "tcpiputils", "virustotal"]
|
93
|
+
options, items = PassiveDNS::CLI.parse_command_line(["-dptv"])
|
94
|
+
assert_equal(options_target, options)
|
95
|
+
assert_equal([], items)
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_output_parsing
|
100
|
+
options_target = {
|
101
|
+
:pdnsdbs => ["passivetotal", "tcpiputils", "virustotal"],
|
102
|
+
:format => "text",
|
103
|
+
:sep => "\t",
|
104
|
+
:recursedepth => 1,
|
105
|
+
:wait => 0,
|
106
|
+
:res => nil,
|
107
|
+
:debug => false,
|
108
|
+
:sqlitedb => nil,
|
109
|
+
:limit => nil,
|
110
|
+
:help => false
|
111
|
+
}
|
112
|
+
|
113
|
+
options_target[:sep] = ","
|
114
|
+
options, items = PassiveDNS::CLI.parse_command_line(["-dptv", "-c", "8.8.8.8"])
|
115
|
+
assert_equal(options_target, options)
|
116
|
+
assert_equal(["8.8.8.8"], items)
|
117
|
+
|
118
|
+
options_target[:sep] = "|"
|
119
|
+
options, items = PassiveDNS::CLI.parse_command_line(["-dptv", "-s", "|", "8.8.8.8"])
|
120
|
+
assert_equal(options_target, options)
|
121
|
+
assert_equal(["8.8.8.8"], items)
|
122
|
+
|
123
|
+
options_target[:sep] = "\t"
|
124
|
+
|
125
|
+
options, items = PassiveDNS::CLI.parse_command_line(["-dptv", "-t", "8.8.8.8"])
|
126
|
+
assert_equal(options_target, options)
|
127
|
+
assert_equal(["8.8.8.8"], items)
|
128
|
+
|
129
|
+
options_target[:format] = "json"
|
130
|
+
options, items = PassiveDNS::CLI.parse_command_line(["-dptv", "-j", "8.8.8.8"])
|
131
|
+
assert_equal(options_target, options)
|
132
|
+
assert_equal(["8.8.8.8"], items)
|
133
|
+
|
134
|
+
options_target[:format] = "xml"
|
135
|
+
options, items = PassiveDNS::CLI.parse_command_line(["-dptv", "-x", "8.8.8.8"])
|
136
|
+
assert_equal(options_target, options)
|
137
|
+
assert_equal(["8.8.8.8"], items)
|
138
|
+
|
139
|
+
options_target[:format] = "yaml"
|
140
|
+
options, items = PassiveDNS::CLI.parse_command_line(["-dptv", "-y", "8.8.8.8"])
|
141
|
+
assert_equal(options_target, options)
|
142
|
+
assert_equal(["8.8.8.8"], items)
|
143
|
+
|
144
|
+
options_target[:format] = "gdf"
|
145
|
+
options, items = PassiveDNS::CLI.parse_command_line(["-dptv", "-g", "8.8.8.8"])
|
146
|
+
assert_equal(options_target, options)
|
147
|
+
assert_equal(["8.8.8.8"], items)
|
148
|
+
|
149
|
+
options_target[:format] = "graphviz"
|
150
|
+
options, items = PassiveDNS::CLI.parse_command_line(["-dptv", "-z", "8.8.8.8"])
|
151
|
+
assert_equal(options_target, options)
|
152
|
+
assert_equal(["8.8.8.8"], items)
|
153
|
+
|
154
|
+
options_target[:format] = "graphml"
|
155
|
+
options, items = PassiveDNS::CLI.parse_command_line(["-dptv", "-m", "8.8.8.8"])
|
156
|
+
assert_equal(options_target, options)
|
157
|
+
assert_equal(["8.8.8.8"], items)
|
158
|
+
|
159
|
+
options_target[:format] = "text"
|
160
|
+
end
|
161
|
+
|
162
|
+
def test_help_debug_parsing
|
163
|
+
options_target = {
|
164
|
+
:pdnsdbs => ["passivetotal", "tcpiputils", "virustotal"],
|
165
|
+
:format => "text",
|
166
|
+
:sep => "\t",
|
167
|
+
:recursedepth => 1,
|
168
|
+
:wait => 0,
|
169
|
+
:res => nil,
|
170
|
+
:debug => false,
|
171
|
+
:sqlitedb => nil,
|
172
|
+
:limit => nil,
|
173
|
+
:help => true
|
174
|
+
}
|
175
|
+
|
176
|
+
options, items = PassiveDNS::CLI.parse_command_line(["-dptv", "-h", "8.8.8.8"])
|
177
|
+
assert_equal(options_target, options)
|
178
|
+
assert_equal(["8.8.8.8"], items)
|
179
|
+
|
180
|
+
options_target[:debug] = true
|
181
|
+
options, items = PassiveDNS::CLI.parse_command_line(["-dptv", "-h", "-v", "8.8.8.8"])
|
182
|
+
assert_equal(options_target, options)
|
183
|
+
assert_equal(["8.8.8.8"], items)
|
184
|
+
end
|
185
|
+
|
186
|
+
def test_state_recursion_parsing
|
187
|
+
options_target = {
|
188
|
+
:pdnsdbs => ["passivetotal", "tcpiputils", "virustotal"],
|
189
|
+
:format => "text",
|
190
|
+
:sep => "\t",
|
191
|
+
:recursedepth => 5,
|
192
|
+
:wait => 30,
|
193
|
+
:res => nil,
|
194
|
+
:debug => false,
|
195
|
+
:sqlitedb => "test.db",
|
196
|
+
:limit => 10,
|
197
|
+
:help => false
|
198
|
+
}
|
199
|
+
|
200
|
+
options, items = PassiveDNS::CLI.parse_command_line(["-dptv", "-f", "test.db", "-r", "5", "-w", "30", "-l", "10", "8.8.8.8"])
|
201
|
+
assert_equal(options_target, options)
|
202
|
+
assert_equal(["8.8.8.8"], items)
|
203
|
+
end
|
204
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: passivedns-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- chrislee35
|
@@ -139,6 +139,7 @@ files:
|
|
139
139
|
- lib/passivedns/client/version.rb
|
140
140
|
- passivedns-client.gemspec
|
141
141
|
- test/helper.rb
|
142
|
+
- test/test_cli.rb
|
142
143
|
- test/test_passivedns-client.rb
|
143
144
|
homepage: https://github.com/chrislee35/passivedns-client
|
144
145
|
licenses:
|
@@ -166,4 +167,5 @@ specification_version: 4
|
|
166
167
|
summary: Query passive DNS databases
|
167
168
|
test_files:
|
168
169
|
- test/helper.rb
|
170
|
+
- test/test_cli.rb
|
169
171
|
- test/test_passivedns-client.rb
|