ruby-nmap 0.9.2 → 0.9.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a8765d23433a0084314d1e77d295a5f4f3634db7
4
- data.tar.gz: af7b74ff8336e49ddb704100fad33f10656ee959
3
+ metadata.gz: '07049218e947bfd368b40b59010f838c9e298f25'
4
+ data.tar.gz: 94176a6041fc4da9a2adcd7ebf4ea9714ff6b6e2
5
5
  SHA512:
6
- metadata.gz: e21d33b52f03a2eeee743c81bb614e919be5ea9f160af50d6f6935de90368bbccba4f9989b070607c417b03cc0a21679c06a12afa4a81c951e8ab3e2ac8288d6
7
- data.tar.gz: 368e3aebd55908e2bc4d0690e58ad51d4aa1c2c66d696d7430d3b53e32f40940348776cd2fdd0bf0bc2c6b47de70b3af325e7de1b8e00981006de433da2f5c53
6
+ metadata.gz: 6b753b489e1f5f8ee6e03ea9162e7a120d3fdfcb97d138f3cd0d6b02f521b0630240322e8ebb76b88a54437095b1ac40e2f2271e1692b0665df8f7203ee8bd7f
7
+ data.tar.gz: f00bec7139dcd52ef9f4d351da5c3821fa0a2f20cb3570927b11b80f0c90f74cdf32876a252f1ad9b4a1b8051921c493af848991896d857b657381431438285f
@@ -1,3 +1,18 @@
1
+ ### 0.9.3 / 2018-05-01
2
+
3
+ * Added missing `Nmap::Task#defeat_icmp_ratelimit` for the
4
+ `--defeat-icmp-ratelimit` option.
5
+ * Added missing `Nmap::Task#nsock_engine` for the `--nsock-engine` option.
6
+ * Added the {Nmap::XML#prescripts} alias.
7
+ * Added the {Nmap::XML#postscripts} alias.
8
+ * Allow `Task#sctp_init_ping` to accept a port Range object.
9
+ * Fixed a typo in the `Task#defeat_rst_ratelimit` name.
10
+ * Fixed the option formatting of `Nmap::Task#syn_discovery`.
11
+ * Fixed the option formatting of `Nmap::Task#ack_discovery`.
12
+ * Fixed the option formatting of `Nmap::Task#udp_discovery`.
13
+ * Fixed the option formatting of `Nmap::Task#sctp_init_ping`.
14
+ * Fixed the option formatting of `Nmap::Task#ip_ping`.
15
+
1
16
  ### 0.9.2 / 2017-01-13
2
17
 
3
18
  * Fix file descriptor leak in {Nmap::XML#initialize} by using
data/Gemfile CHANGED
@@ -10,5 +10,5 @@ group :development do
10
10
  gem 'json'
11
11
  gem 'simplecov', '~> 0.7'
12
12
  gem 'kramdown'
13
- gem 'yard', '~> 0.8'
13
+ gem 'yard', '~> 0.9'
14
14
  end
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009-2017 Postmodern
1
+ Copyright (c) 2009-2018 Postmodern
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -32,6 +32,15 @@ Run Nmap from Ruby:
32
32
  nmap.targets = '192.168.1.*'
33
33
  end
34
34
 
35
+ Run `sudo nmap` from Ruby:
36
+
37
+ require 'nmap/program'
38
+
39
+ Nmap::Program.sudo_scan do |nmap|
40
+ nmap.syn_scan = true
41
+ # ...
42
+ end
43
+
35
44
  Parse Nmap XML scan files:
36
45
 
37
46
  require 'nmap/xml'
@@ -83,7 +92,7 @@ Print NSE script output from an XML scan file:
83
92
 
84
93
  ## License
85
94
 
86
- Copyright (c) 2009-2017 Postmodern
95
+ Copyright (c) 2009-2018 Postmodern
87
96
 
88
97
  See {file:LICENSE.txt} for license information.
89
98
 
data/Rakefile CHANGED
@@ -12,11 +12,9 @@ end
12
12
 
13
13
  require 'rake'
14
14
  require 'rake/clean'
15
-
16
15
  CLEAN.include('spec/*.xml')
17
16
 
18
17
  require 'rubygems/tasks'
19
-
20
18
  Gem::Tasks.new
21
19
 
22
20
  require 'rspec/core/rake_task'
@@ -63,7 +63,7 @@ module Nmap
63
63
  #
64
64
  def status
65
65
  unless @status
66
- status = @node.at('status')
66
+ status = @node.at_xpath('status')
67
67
 
68
68
  @status = Status.new(
69
69
  status['state'].to_sym,
@@ -120,7 +120,7 @@ module Nmap
120
120
  # The MAC address of the host.
121
121
  #
122
122
  def mac
123
- @mac ||= if (addr = @node.at("address[@addrtype='mac']"))
123
+ @mac ||= if (addr = @node.at_xpath("address[@addrtype='mac']"))
124
124
  addr['addr']
125
125
  end
126
126
  end
@@ -134,7 +134,7 @@ module Nmap
134
134
  # @since 0.8.0
135
135
  #
136
136
  def vendor
137
- @vendor ||= if (vendor = @node.at("address/@vendor"))
137
+ @vendor ||= if (vendor = @node.at_xpath("address/@vendor"))
138
138
  vendor.inner_text
139
139
  end
140
140
  end
@@ -146,7 +146,7 @@ module Nmap
146
146
  # The IPv4 address of the host.
147
147
  #
148
148
  def ipv4
149
- @ipv4 ||= if (addr = @node.at("address[@addrtype='ipv4']"))
149
+ @ipv4 ||= if (addr = @node.at_xpath("address[@addrtype='ipv4']"))
150
150
  addr['addr']
151
151
  end
152
152
  end
@@ -158,7 +158,7 @@ module Nmap
158
158
  # The IPv6 address of the host.
159
159
  #
160
160
  def ipv6
161
- @ipv6 ||= if (addr = @node.at("address[@addrtype='ipv6']"))
161
+ @ipv6 ||= if (addr = @node.at_xpath("address[@addrtype='ipv6']"))
162
162
  addr['addr']
163
163
  end
164
164
  end
@@ -240,7 +240,7 @@ module Nmap
240
240
  # The OS guessing information.
241
241
  #
242
242
  def os
243
- @os ||= if (os = @node.at('os'))
243
+ @os ||= if (os = @node.at_xpath('os'))
244
244
  OS.new(os)
245
245
  end
246
246
 
@@ -263,7 +263,7 @@ module Nmap
263
263
  # @since 0.7.0
264
264
  #
265
265
  def uptime
266
- @uptime ||= if (uptime = @node.at('uptime'))
266
+ @uptime ||= if (uptime = @node.at_xpath('uptime'))
267
267
  Uptime.new(
268
268
  uptime['seconds'].to_i,
269
269
  Time.parse(uptime['lastboot'])
@@ -287,7 +287,7 @@ module Nmap
287
287
  # The parsed object.
288
288
  #
289
289
  def tcp_sequence
290
- @tcp_sequence ||= if (seq = @node.at('tcpsequence'))
290
+ @tcp_sequence ||= if (seq = @node.at_xpath('tcpsequence'))
291
291
  TcpSequence.new(seq)
292
292
  end
293
293
 
@@ -317,7 +317,7 @@ module Nmap
317
317
  # The parsed object.
318
318
  #
319
319
  def ip_id_sequence
320
- @ip_id_sequence ||= if (seq = @node.at('ipidsequence'))
320
+ @ip_id_sequence ||= if (seq = @node.at_xpath('ipidsequence'))
321
321
  IpIdSequence.new(seq)
322
322
  end
323
323
 
@@ -347,7 +347,7 @@ module Nmap
347
347
  # The parsed object.
348
348
  #
349
349
  def tcp_ts_sequence
350
- @tcp_ts_sequence ||= if (seq = @node.at('tcptssequence'))
350
+ @tcp_ts_sequence ||= if (seq = @node.at_xpath('tcptssequence'))
351
351
  TcpTsSequence.new(seq)
352
352
  end
353
353
 
@@ -532,7 +532,7 @@ module Nmap
532
532
  # @since 0.9.0
533
533
  #
534
534
  def host_script
535
- @host_script ||= if (hostscript = @node.at('hostscript'))
535
+ @host_script ||= if (hostscript = @node.at_xpath('hostscript'))
536
536
  HostScript.new(hostscript)
537
537
  end
538
538
  end
@@ -552,7 +552,7 @@ module Nmap
552
552
  # @since 0.7.0
553
553
  #
554
554
  def traceroute
555
- @traceroute ||= if (trace = @node.at('trace'))
555
+ @traceroute ||= if (trace = @node.at_xpath('trace'))
556
556
  Traceroute.new(trace)
557
557
  end
558
558
 
@@ -109,7 +109,7 @@ module Nmap
109
109
  # The OS fingerprint.
110
110
  #
111
111
  def fingerprint
112
- @fingerprint ||= if (fingerprint = @node.at("osfingerprint/@fingerprint"))
112
+ @fingerprint ||= if (fingerprint = @node.at_xpath("osfingerprint/@fingerprint"))
113
113
  fingerprint.inner_text
114
114
  end
115
115
  end
@@ -46,7 +46,7 @@ module Nmap
46
46
  # The state of the port (`:open`, `:filtered` or `:closed`).
47
47
  #
48
48
  def state
49
- @state ||= @node.at('state/@state').inner_text.to_sym
49
+ @state ||= @node.at_xpath('state/@state').inner_text.to_sym
50
50
  end
51
51
 
52
52
  #
@@ -56,7 +56,7 @@ module Nmap
56
56
  # How the port was discovered.
57
57
  #
58
58
  def reason
59
- @reason ||= @node.at('state/@reason').inner_text
59
+ @reason ||= @node.at_xpath('state/@reason').inner_text
60
60
  end
61
61
 
62
62
  #
@@ -68,7 +68,7 @@ module Nmap
68
68
  # @since 0.6.0
69
69
  #
70
70
  def service
71
- @service_info ||= if (service = @node.at('service'))
71
+ @service_info ||= if (service = @node.at_xpath('service'))
72
72
  Service.new(service)
73
73
  end
74
74
  end
@@ -95,7 +95,9 @@ module Nmap
95
95
  # * `--max-scan-delay` - `nmap.max_scan_delay`
96
96
  # * `--min-rate` - `nmap.min_rate`
97
97
  # * `--max-rate` - `nmap.max_rate`
98
- # * `--default-rst-ratelimit` - `nmap.default_rst_ratelimit`
98
+ # * `--defeat-rst-ratelimit` - `nmap.defeat_rst_ratelimit`
99
+ # * `--defeat-icmp-ratelimit` - `nmap.defeat_icmp_ratelimit`
100
+ # * `--nsock-engine` - `nmap.nsock_engine`
99
101
  # * `-T` - `nmap.timing_template`
100
102
  # * `-T0` - `nmap.paranoid_timing`
101
103
  # * `-T1` - `nmap.sneaky_timing`
@@ -180,14 +182,24 @@ module Nmap
180
182
  short_option :flag => '-sL', :name => :list
181
183
  short_option :flag => '-sn', :name => :ping
182
184
  short_option :flag => '-Pn', :name => :skip_discovery
183
- short_option :flag => '-PS', :name => :syn_discovery
184
- short_option :flag => '-PA', :name => :ack_discovery
185
- short_option :flag => '-PU', :name => :udp_discovery
186
- short_option :flag => '-PY', :name => :sctp_init_ping
185
+ short_option :flag => '-PS', :name => :syn_discovery do |opt,value|
186
+ ["#{opt.flag}#{format_port_list(value)}"]
187
+ end
188
+ short_option :flag => '-PA', :name => :ack_discovery do |opt,value|
189
+ ["#{opt.flag}#{format_port_list(value)}"]
190
+ end
191
+ short_option :flag => '-PU', :name => :udp_discovery do |opt,value|
192
+ ["#{opt.flag}#{format_port_list(value)}"]
193
+ end
194
+ short_option :flag => '-PY', :name => :sctp_init_ping do |opt,value|
195
+ ["#{opt.flag}#{format_port_list(value)}"]
196
+ end
187
197
  short_option :flag => '-PE', :name => :icmp_echo_discovery
188
198
  short_option :flag => '-PP', :name => :icmp_timestamp_discovery
189
199
  short_option :flag => '-PM', :name => :icmp_netmask_discovery
190
- short_option :flag => '-PO', :name => :ip_ping
200
+ short_option :flag => '-PO', :name => :ip_ping do |opt,value|
201
+ ["#{opt.flag}#{format_protocol_list(value)}"]
202
+ end
191
203
  short_option :flag => '-PR', :name => :arp_ping
192
204
  long_option :flag => '--traceroute', :name => :traceroute
193
205
  short_option :flag => '-n', :name => :disable_dns
@@ -215,17 +227,9 @@ module Nmap
215
227
  # PORT SPECIFICATION AND SCAN ORDER:
216
228
  short_option :flag => '-p', :name => :ports do |opt,value|
217
229
  unless value.empty?
218
- [opt.flag, value.map { |port|
219
- case port
220
- when Range
221
- "#{port.first}-#{port.last}"
222
- else
223
- port.to_s
224
- end
225
- }.join(',')]
230
+ [opt.flag, format_port_list(value)]
226
231
  end
227
232
  end
228
-
229
233
  short_option :flag => '-F', :name => :fast
230
234
  short_option :flag => '-r', :name => :consecutively
231
235
  long_option :flag => '--top-ports'
@@ -268,7 +272,9 @@ module Nmap
268
272
  long_option :flag => '--max-scan-delay'
269
273
  long_option :flag => '--min-rate'
270
274
  long_option :flag => '--max-rate'
271
- long_option :flag => '--default-rst-ratelimit'
275
+ long_option :flag => '--defeat-rst-ratelimit'
276
+ long_option :flag => '--defeat-icmp-ratelimit'
277
+ long_option :flag => '--nsock-engine'
272
278
  short_option :flag => '-T', :name => :timing_template
273
279
  short_option :flag => '-T0', :name => :paranoid_timing
274
280
  short_option :flag => '-T1', :name => :sneaky_timing
@@ -334,5 +340,42 @@ module Nmap
334
340
 
335
341
  non_option :tailing => true, :name => :targets
336
342
 
343
+ private
344
+
345
+ #
346
+ # Fomats a port list.
347
+ #
348
+ # @param [Array<Integer,Range>] ports
349
+ # The port ranges.
350
+ #
351
+ # @return [String]
352
+ # Comma separated string.
353
+ #
354
+ def self.format_port_list(ports)
355
+ ports.map { |port|
356
+ case port
357
+ when Range
358
+ "#{port.first}-#{port.last}"
359
+ else
360
+ port.to_s
361
+ end
362
+ }.join(',')
363
+ end
364
+
365
+ #
366
+ # Formats a protocol list.
367
+ #
368
+ # @param [Array<Integer,Range>] protocols
369
+ # The IP protocol numbers.
370
+ #
371
+ # @return [String]
372
+ # Comma separated string.
373
+ #
374
+ def self.format_protocol_list(protocols)
375
+ # NOTE: the man page says the protocol list is similar to the format of
376
+ # a port range.
377
+ format_port_list(protocols)
378
+ end
379
+
337
380
  end
338
381
  end
@@ -1,4 +1,4 @@
1
1
  module Nmap
2
2
  # ruby-nmap version
3
- VERSION = '0.9.2'
3
+ VERSION = '0.9.3'
4
4
  end
@@ -255,6 +255,8 @@ module Nmap
255
255
  end
256
256
  end
257
257
 
258
+ alias prescripts prescript
259
+
258
260
  #
259
261
  # The NSE scripts ran after the scan.
260
262
  #
@@ -269,6 +271,8 @@ module Nmap
269
271
  end
270
272
  end
271
273
 
274
+ alias postscripts postscript
275
+
272
276
  #
273
277
  # Parses the hosts in the scan.
274
278
  #
@@ -3,34 +3,148 @@ require 'nmap/task'
3
3
 
4
4
  describe Task do
5
5
  describe "#ports=" do
6
- it "should ignore empty port Arrays" do
7
- subject.ports = []
6
+ context "when given an empty Array" do
7
+ before { subject.ports = [] }
8
8
 
9
- expect(subject.arguments).to eq([])
9
+ it "should ignore empty port Arrays" do
10
+ subject.ports = []
11
+
12
+ expect(subject.arguments).to eq([])
13
+ end
14
+ end
15
+
16
+ context "when given a String" do
17
+ let(:ports) { '80,21,25' }
18
+
19
+ before { subject.ports = ports }
20
+
21
+ it "should emit the String as is" do
22
+ expect(subject.arguments).to eq(['-p', ports])
23
+ end
10
24
  end
11
25
 
12
- it "should format a String of ports" do
13
- subject.ports = '80,21,25'
26
+ context "when given an Array of Strings" do
27
+ let(:ports) { %w[80 21 25] }
28
+
29
+ before { subject.ports = ports }
30
+
31
+ it "should format an Array of String ports" do
32
+ expect(subject.arguments).to eq(['-p', ports.join(',')])
33
+ end
34
+ end
35
+
36
+ context "when given an Array of Integers" do
37
+ let(:ports) { [80, 21, 25] }
38
+
39
+ before { subject.ports = ports }
40
+
41
+ it "should format an Array of Integer ports" do
42
+ expect(subject.arguments).to eq(['-p', ports.join(',')])
43
+ end
44
+ end
45
+
46
+ context "when given an Array containing a Range" do
47
+ let(:ports) { [80, 21..25] }
48
+
49
+ before { subject.ports = ports }
50
+
51
+ it "should format the Range" do
52
+ expect(subject.arguments).to eq([
53
+ '-p', "#{ports[0]},#{ports[1].begin}-#{ports[1].end}"
54
+ ])
55
+ end
56
+ end
57
+ end
58
+
59
+ shared_examples "optional port range" do |flag,method|
60
+ before { subject.send(:"#{method}=",ports) }
61
+
62
+ context "when given a Boolean" do
63
+ let(:ports) { true }
64
+
65
+ it "should emit the '#{flag}' option flag" do
66
+ expect(subject.arguments).to eq([flag])
67
+ end
68
+ end
69
+
70
+ context "when given an empty Array" do
71
+ let(:ports) { [] }
72
+
73
+ it "should emit the '#{flag}' option flag" do
74
+ expect(subject.arguments).to eq([flag])
75
+ end
76
+ end
77
+
78
+ context "when given an Array of Integers" do
79
+ let(:ports) { [80, 21, 25] }
80
+
81
+ it "should emit the '#{flag}' option flag with the Integer ports" do
82
+ expect(subject.arguments).to eq(["#{flag}#{ports.join(',')}"])
83
+ end
84
+ end
85
+
86
+ context "when given an Array containing a Range" do
87
+ let(:ports) { [80, 21..25] }
88
+
89
+ it "should emit the '#{flag}' option flag with the Integer ports" do
90
+ expect(subject.arguments).to eq([
91
+ "#{flag}#{ports[0]},#{ports[1].begin}-#{ports[1].end}"
92
+ ])
93
+ end
94
+ end
95
+ end
96
+
97
+ describe "#syn_discovery" do
98
+ include_examples "optional port range", '-PS', :syn_discovery
99
+ end
100
+
101
+ describe "#ack_discovery" do
102
+ include_examples "optional port range", '-PA', :ack_discovery
103
+ end
104
+
105
+ describe "#udp_discovery" do
106
+ include_examples "optional port range", '-PU', :udp_discovery
107
+ end
108
+
109
+ describe "#sctp_init_ping" do
110
+ include_examples "optional port range", '-PY', :sctp_init_ping
111
+ end
112
+
113
+ describe "#ip_ping" do
114
+ before { subject.ip_ping = protocols }
115
+
116
+ context "when given a Boolean" do
117
+ let(:protocols) { true }
14
118
 
15
- expect(subject.arguments).to eq(%w[-p 80,21,25])
119
+ it "should emit the '-PO' option flag" do
120
+ expect(subject.arguments).to eq(['-PO'])
121
+ end
16
122
  end
17
123
 
18
- it "should format an Array of String ports" do
19
- subject.ports = %w[80 21 25]
124
+ context "when given an empty Array" do
125
+ let(:protocols) { [] }
20
126
 
21
- expect(subject.arguments).to eq(%w[-p 80,21,25])
127
+ it "should emit the '-PO' option flag" do
128
+ expect(subject.arguments).to eq(['-PO'])
129
+ end
22
130
  end
23
131
 
24
- it "should format an Array of Integer ports" do
25
- subject.ports = [80, 21, 25]
132
+ context "when given an Array of Integers" do
133
+ let(:protocols) { [80, 21, 25] }
26
134
 
27
- expect(subject.arguments).to eq(%w[-p 80,21,25])
135
+ it "should emit the '-PO' option flag with the Integer ports" do
136
+ expect(subject.arguments).to eq(["-PO#{protocols.join(',')}"])
137
+ end
28
138
  end
29
139
 
30
- it "should format a Range of ports" do
31
- subject.ports = [80, 21..25]
140
+ context "when given an Array containing a Range" do
141
+ let(:protocols) { [80, 21..25] }
32
142
 
33
- expect(subject.arguments).to eq(%w[-p 80,21-25])
143
+ it "should emit the '-PO' option flag with the Integer ports" do
144
+ expect(subject.arguments).to eq([
145
+ "-PO#{protocols[0]},#{protocols[1].begin}-#{protocols[1].end}"
146
+ ])
147
+ end
34
148
  end
35
149
  end
36
150
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-nmap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
4
+ version: 0.9.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Postmodern
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-14 00:00:00.000000000 Z
11
+ date: 2018-05-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -157,7 +157,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
157
157
  requirements:
158
158
  - nmap >= 5.00
159
159
  rubyforge_project:
160
- rubygems_version: 2.5.2
160
+ rubygems_version: 2.6.14
161
161
  signing_key:
162
162
  specification_version: 4
163
163
  summary: A Ruby interface to Nmap.