ruby-nmap 0.10.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/.document +1 -0
  3. data/.editorconfig +11 -0
  4. data/.github/workflows/ruby.yml +31 -0
  5. data/ChangeLog.md +118 -71
  6. data/Gemfile +11 -5
  7. data/LICENSE.txt +1 -1
  8. data/README.md +88 -50
  9. data/Rakefile +5 -0
  10. data/UPGRADING.md +47 -0
  11. data/gemspec.yml +5 -5
  12. data/lib/nmap/command.rb +765 -0
  13. data/lib/nmap/version.rb +1 -1
  14. data/lib/nmap/xml/address.rb +38 -0
  15. data/lib/nmap/xml/cpe/url.rb +80 -0
  16. data/lib/nmap/xml/cpe.rb +47 -0
  17. data/lib/nmap/xml/hop.rb +22 -0
  18. data/lib/nmap/xml/host.rb +546 -0
  19. data/lib/nmap/xml/host_script.rb +26 -0
  20. data/lib/nmap/xml/hostname.rb +44 -0
  21. data/lib/nmap/xml/ip_id_sequence.rb +26 -0
  22. data/lib/nmap/xml/os.rb +131 -0
  23. data/lib/nmap/xml/os_class.rb +86 -0
  24. data/lib/nmap/xml/os_match.rb +22 -0
  25. data/lib/nmap/xml/port.rb +114 -0
  26. data/lib/nmap/xml/postscript.rb +26 -0
  27. data/lib/nmap/xml/prescript.rb +26 -0
  28. data/lib/nmap/xml/run_stat.rb +22 -0
  29. data/lib/nmap/xml/scan.rb +38 -0
  30. data/lib/nmap/xml/scan_task.rb +55 -0
  31. data/lib/nmap/xml/scanner.rb +22 -0
  32. data/lib/nmap/xml/script.rb +110 -0
  33. data/lib/nmap/xml/scripts.rb +33 -0
  34. data/lib/nmap/xml/sequence.rb +52 -0
  35. data/lib/nmap/xml/service.rb +172 -0
  36. data/lib/nmap/xml/status.rb +22 -0
  37. data/lib/nmap/xml/tcp_sequence.rb +48 -0
  38. data/lib/nmap/xml/tcp_ts_sequence.rb +26 -0
  39. data/lib/nmap/xml/traceroute.rb +73 -0
  40. data/lib/nmap/xml/uptime.rb +22 -0
  41. data/lib/nmap/xml.rb +31 -44
  42. data/spec/command_spec.rb +726 -0
  43. data/spec/fixtures/down_host_scan.xml +16 -0
  44. data/spec/{address_spec.rb → xml/address_spec.rb} +2 -2
  45. data/spec/{cpe → xml/cpe}/url_spec.rb +1 -1
  46. data/spec/{cpe_examples.rb → xml/cpe_examples.rb} +1 -1
  47. data/spec/{hop_spec.rb → xml/hop_spec.rb} +2 -2
  48. data/spec/{host_script_spec.rb → xml/host_script_spec.rb} +2 -2
  49. data/spec/{host_spec.rb → xml/host_spec.rb} +8 -8
  50. data/spec/{hostname_spec.rb → xml/hostname_spec.rb} +2 -2
  51. data/spec/{ip_id_sequence_spec.rb → xml/ip_id_sequence_spec.rb} +3 -3
  52. data/spec/{os_class_spec.rb → xml/os_class_spec.rb} +3 -3
  53. data/spec/{os_match_spec.rb → xml/os_match_spec.rb} +2 -2
  54. data/spec/{os_spec.rb → xml/os_spec.rb} +3 -3
  55. data/spec/{port_spec.rb → xml/port_spec.rb} +4 -5
  56. data/spec/{postscript_spec.rb → xml/postscript_spec.rb} +2 -2
  57. data/spec/{prescript_spec.rb → xml/prescript_spec.rb} +2 -2
  58. data/spec/{run_stat_spec.rb → xml/run_stat_spec.rb} +2 -2
  59. data/spec/{scan_spec.rb → xml/scan_spec.rb} +2 -2
  60. data/spec/{scan_task_spec.rb → xml/scan_task_spec.rb} +6 -6
  61. data/spec/{scanner_spec.rb → xml/scanner_spec.rb} +3 -3
  62. data/spec/xml/script_spec.rb +137 -0
  63. data/spec/xml/scripts_examples.rb +19 -0
  64. data/spec/{sequence_examples.rb → xml/sequence_examples.rb} +1 -0
  65. data/spec/{service_spec.rb → xml/service_spec.rb} +31 -5
  66. data/spec/{status_spec.rb → xml/status_spec.rb} +2 -2
  67. data/spec/{tcp_sequence_spec.rb → xml/tcp_sequence_spec.rb} +3 -3
  68. data/spec/{tcp_ts_sequence_spec.rb → xml/tcp_ts_sequence_spec.rb} +3 -3
  69. data/spec/{traceroute_spec.rb → xml/traceroute_spec.rb} +3 -3
  70. data/spec/{uptime_spec.rb → xml/uptime_spec.rb} +2 -2
  71. data/spec/xml_spec.rb +73 -44
  72. metadata +72 -66
  73. data/.travis.yml +0 -16
  74. data/lib/nmap/address.rb +0 -34
  75. data/lib/nmap/cpe/url.rb +0 -78
  76. data/lib/nmap/cpe.rb +0 -45
  77. data/lib/nmap/hop.rb +0 -20
  78. data/lib/nmap/host.rb +0 -587
  79. data/lib/nmap/host_script.rb +0 -18
  80. data/lib/nmap/hostname.rb +0 -42
  81. data/lib/nmap/ip_id_sequence.rb +0 -24
  82. data/lib/nmap/os.rb +0 -127
  83. data/lib/nmap/os_class.rb +0 -82
  84. data/lib/nmap/os_match.rb +0 -18
  85. data/lib/nmap/port.rb +0 -110
  86. data/lib/nmap/postscript.rb +0 -16
  87. data/lib/nmap/prescript.rb +0 -16
  88. data/lib/nmap/program.rb +0 -102
  89. data/lib/nmap/run_stat.rb +0 -20
  90. data/lib/nmap/scan.rb +0 -34
  91. data/lib/nmap/scan_task.rb +0 -53
  92. data/lib/nmap/scanner.rb +0 -18
  93. data/lib/nmap/scripts.rb +0 -71
  94. data/lib/nmap/sequence.rb +0 -50
  95. data/lib/nmap/service.rb +0 -170
  96. data/lib/nmap/status.rb +0 -18
  97. data/lib/nmap/task.rb +0 -387
  98. data/lib/nmap/tcp_sequence.rb +0 -46
  99. data/lib/nmap/tcp_ts_sequence.rb +0 -22
  100. data/lib/nmap/traceroute.rb +0 -71
  101. data/lib/nmap/uptime.rb +0 -20
  102. data/spec/scripts_examples.rb +0 -35
  103. data/spec/task_spec.rb +0 -150
data/lib/nmap/host.rb DELETED
@@ -1,587 +0,0 @@
1
- require 'nmap/status'
2
- require 'nmap/address'
3
- require 'nmap/hostname'
4
- require 'nmap/os'
5
- require 'nmap/port'
6
- require 'nmap/ip_id_sequence'
7
- require 'nmap/tcp_sequence'
8
- require 'nmap/tcp_ts_sequence'
9
- require 'nmap/uptime'
10
- require 'nmap/traceroute'
11
- require 'nmap/host_script'
12
-
13
- require 'nokogiri'
14
- require 'time'
15
-
16
- module Nmap
17
- #
18
- # Wraps a `host` XML element.
19
- #
20
- class Host
21
-
22
- include Enumerable
23
-
24
- #
25
- # Creates a new Host object.
26
- #
27
- # @param [Nokogiri::XML::Node] node
28
- # The XML node that contains the host information.
29
- #
30
- def initialize(node)
31
- @node = node
32
- end
33
-
34
- #
35
- # The time the host was first scanned.
36
- #
37
- # @return [Time]
38
- # The time the host was first scanned.
39
- #
40
- # @since 0.1.2
41
- #
42
- def start_time
43
- @start_time ||= Time.at(@node['starttime'].to_i)
44
- end
45
-
46
- #
47
- # The time the host was last scanned.
48
- #
49
- # @return [Time]
50
- # The time the host was last scanned.
51
- #
52
- # @since 0.1.2
53
- #
54
- def end_time
55
- @end_time ||= Time.at(@node['endtime'].to_i)
56
- end
57
-
58
- #
59
- # Parses the status of the host.
60
- #
61
- # @return [Status]
62
- # The status of the host.
63
- #
64
- def status
65
- unless @status
66
- status = @node.at_xpath('status')
67
-
68
- @status = Status.new(
69
- status['state'].to_sym,
70
- status['reason'],
71
- status['reason_ttl'].to_i
72
- )
73
- end
74
-
75
- return @status
76
- end
77
-
78
- #
79
- # Parses each address of the host.
80
- #
81
- # @yield [addr]
82
- # Each parsed address will be pass to a given block.
83
- #
84
- # @yieldparam [Address] addr
85
- # A address of the host.
86
- #
87
- # @return [Host, Enumerator]
88
- # The host.
89
- # If no block was given, an enumerator will be returned.
90
- #
91
- def each_address
92
- return enum_for(__method__) unless block_given?
93
-
94
- @node.xpath("address[@addr]").each do |addr|
95
- address = Address.new(
96
- addr['addrtype'].to_sym,
97
- addr['addr'],
98
- addr['vendor']
99
- )
100
-
101
- yield address
102
- end
103
-
104
- return self
105
- end
106
-
107
- #
108
- # Parses the addresses of the host.
109
- #
110
- # @return [Array<Host>]
111
- # The addresses of the host.
112
- #
113
- def addresses
114
- each_address.to_a
115
- end
116
-
117
- #
118
- # Parses the MAC address of the host.
119
- #
120
- # @return [String]
121
- # The MAC address of the host.
122
- #
123
- def mac
124
- @mac ||= if (addr = @node.at_xpath("address[@addrtype='mac']"))
125
- addr['addr']
126
- end
127
- end
128
-
129
- #
130
- # Parses the MAC vendor of the host.
131
- #
132
- # @return [String]
133
- # The Mac Vendor of the host.
134
- #
135
- # @since 0.8.0
136
- #
137
- def vendor
138
- @vendor ||= if (vendor = @node.at_xpath("address/@vendor"))
139
- vendor.inner_text
140
- end
141
- end
142
-
143
- #
144
- # Parses the IPv4 address of the host.
145
- #
146
- # @return [String]
147
- # The IPv4 address of the host.
148
- #
149
- def ipv4
150
- @ipv4 ||= if (addr = @node.at_xpath("address[@addrtype='ipv4']"))
151
- addr['addr']
152
- end
153
- end
154
-
155
- #
156
- # Parses the IPv6 address of the host.
157
- #
158
- # @return [String]
159
- # The IPv6 address of the host.
160
- #
161
- def ipv6
162
- @ipv6 ||= if (addr = @node.at_xpath("address[@addrtype='ipv6']"))
163
- addr['addr']
164
- end
165
- end
166
-
167
- #
168
- # The IP address of the host.
169
- #
170
- # @return [String]
171
- # The IPv4 or IPv6 address of the host.
172
- #
173
- def ip
174
- ipv6 || ipv4
175
- end
176
-
177
- #
178
- # The address of the host.
179
- #
180
- # @return [String]
181
- # The IP or MAC address of the host.
182
- #
183
- def address
184
- ip || mac
185
- end
186
-
187
- #
188
- # Parses the hostnames of the host.
189
- #
190
- # @yield [host]
191
- # Each parsed hostname will be passed to the given block.
192
- #
193
- # @yieldparam [Hostname] host
194
- # A hostname of the host.
195
- #
196
- # @return [Host, Enumerator]
197
- # The host.
198
- # If no block was given, an enumerator will be returned.
199
- #
200
- def each_hostname
201
- return enum_for(__method__) unless block_given?
202
-
203
- @node.xpath("hostnames/hostname[@name]").each do |host|
204
- yield Hostname.new(host['type'],host['name'])
205
- end
206
-
207
- return self
208
- end
209
-
210
- #
211
- # Parses the hostnames of the host.
212
- #
213
- # @return [Array<Hostname>]
214
- # The hostnames of the host.
215
- #
216
- def hostnames
217
- each_hostname.to_a
218
- end
219
-
220
- #
221
- # The primary hostname of the host.
222
- #
223
- # @return [Hostname, nil]
224
- #
225
- # @since 0.8.0
226
- #
227
- def hostname
228
- each_hostname.first
229
- end
230
-
231
- #
232
- # Parses the OS guessing information of the host.
233
- #
234
- # @yield [os]
235
- # If a block is given, it will be passed the OS guessing information.
236
- #
237
- # @yieldparam [OS] os
238
- # The OS guessing information.
239
- #
240
- # @return [OS]
241
- # The OS guessing information.
242
- #
243
- def os
244
- @os ||= if (os = @node.at_xpath('os'))
245
- OS.new(os)
246
- end
247
-
248
- yield @os if (@os && block_given?)
249
- return @os
250
- end
251
-
252
- #
253
- # Parses the Uptime analysis of the host.
254
- #
255
- # @yield [uptime]
256
- # If a block is given, it will be passed the resulting object
257
- #
258
- # @yieldparam [Uptime]
259
- # Uptime value.
260
- #
261
- # @return [Uptime]
262
- # The parsed object.
263
- #
264
- # @since 0.7.0
265
- #
266
- def uptime
267
- @uptime ||= if (uptime = @node.at_xpath('uptime'))
268
- Uptime.new(
269
- uptime['seconds'].to_i,
270
- Time.parse(uptime['lastboot'])
271
- )
272
- end
273
-
274
- yield @uptime if (@uptime && block_given?)
275
- return @uptime
276
- end
277
-
278
- #
279
- # Parses the Tcp Sequence number analysis of the host.
280
- #
281
- # @yield [sequence]
282
- # If a block is given, it will be passed the resulting object
283
- #
284
- # @yieldparam [TcpSequence] sequence
285
- # Tcp Sequence number analysis.
286
- #
287
- # @return [TcpSequence]
288
- # The parsed object.
289
- #
290
- def tcp_sequence
291
- @tcp_sequence ||= if (seq = @node.at_xpath('tcpsequence'))
292
- TcpSequence.new(seq)
293
- end
294
-
295
- yield @tcp_sequence if (@tcp_sequence && block_given?)
296
- return @tcp_sequence
297
- end
298
-
299
- #
300
- # @deprecated Use {#tcp_sequence} instead.
301
- #
302
- def tcpsequence(&block)
303
- warn "DEPRECATION: use #{self.class}#tcp_sequence instead"
304
-
305
- tcp_sequence(&block)
306
- end
307
-
308
- #
309
- # Parses the IPID sequence number analysis of the host.
310
- #
311
- # @yield [ipidsequence]
312
- # If a block is given, it will be passed the resulting object
313
- #
314
- # @yieldparam [IpIdSequence] ipidsequence
315
- # IPID Sequence number analysis.
316
- #
317
- # @return [IpIdSequence]
318
- # The parsed object.
319
- #
320
- def ip_id_sequence
321
- @ip_id_sequence ||= if (seq = @node.at_xpath('ipidsequence'))
322
- IpIdSequence.new(seq)
323
- end
324
-
325
- yield @ip_id_sequence if (@ip_id_sequence && block_given?)
326
- return @ip_id_sequence
327
- end
328
-
329
- #
330
- # @deprecated Use {#ip_id_sequence} instead.
331
- #
332
- def ipidsequence(&block)
333
- warn "DEPRECATION: use #{self.class}#ip_id_sequence instead"
334
-
335
- ip_id_sequence(&block)
336
- end
337
-
338
- #
339
- # Parses the TCP Timestamp sequence number analysis of the host.
340
- #
341
- # @yield [tcptssequence]
342
- # If a block is given, it will be passed the resulting object
343
- #
344
- # @yieldparam [TcpTsSequence] tcptssequence
345
- # TCP Timestamp Sequence number analysis.
346
- #
347
- # @return [TcpTsSequence]
348
- # The parsed object.
349
- #
350
- def tcp_ts_sequence
351
- @tcp_ts_sequence ||= if (seq = @node.at_xpath('tcptssequence'))
352
- TcpTsSequence.new(seq)
353
- end
354
-
355
- yield @tcp_ts_sequence if (@tcp_ts_sequence && block_given?)
356
- return @tcp_ts_sequence
357
- end
358
-
359
- #
360
- # @deprecated Use {#tcp_ts_sequence} instead.
361
- #
362
- def tcptssequence(&block)
363
- warn "DEPRECATION: use #{self.class}#tcp_ts_sequence instead"
364
-
365
- tcp_ts_sequence(&block)
366
- end
367
-
368
- #
369
- # Parses the scanned ports of the host.
370
- #
371
- # @yield [port]
372
- # Each scanned port of the host.
373
- #
374
- # @yieldparam [Port] port
375
- # A scanned port of the host.
376
- #
377
- # @return [Host, Enumerator]
378
- # The host.
379
- # If no block was given, an enumerator will be returned.
380
- #
381
- def each_port
382
- return enum_for(__method__) unless block_given?
383
-
384
- @node.xpath("ports/port").each do |port|
385
- yield Port.new(port)
386
- end
387
-
388
- return self
389
- end
390
-
391
- #
392
- # Parses the scanned ports of the host.
393
- #
394
- # @return [Array<Port>]
395
- # The scanned ports of the host.
396
- #
397
- def ports
398
- each_port.to_a
399
- end
400
-
401
- #
402
- # Parses the open ports of the host.
403
- #
404
- # @yield [port]
405
- # Each open port of the host.
406
- #
407
- # @yieldparam [Port] port
408
- # An open scanned port of the host.
409
- #
410
- # @return [Host, Enumerator]
411
- # The host.
412
- # If no block was given, an enumerator will be returned.
413
- #
414
- def each_open_port
415
- return enum_for(__method__) unless block_given?
416
-
417
- @node.xpath("ports/port[state/@state='open']").each do |port|
418
- yield Port.new(port)
419
- end
420
-
421
- return self
422
- end
423
-
424
- #
425
- # Parses the open ports of the host.
426
- #
427
- # @return [Array<Port>]
428
- # The open ports of the host.
429
- #
430
- def open_ports
431
- each_open_port.to_a
432
- end
433
-
434
- #
435
- # Parses the TCP ports of the host.
436
- #
437
- # @yield [port]
438
- # Each TCP port of the host.
439
- #
440
- # @yieldparam [Port] port
441
- # An TCP scanned port of the host.
442
- #
443
- # @return [Host, Enumerator]
444
- # The host.
445
- # If no block was given, an enumerator will be returned.
446
- #
447
- def each_tcp_port
448
- return enum_for(__method__) unless block_given?
449
-
450
- @node.xpath("ports/port[@protocol='tcp']").each do |port|
451
- yield Port.new(port)
452
- end
453
-
454
- return self
455
- end
456
-
457
- #
458
- # Parses the TCP ports of the host.
459
- #
460
- # @return [Array<Port>]
461
- # The TCP ports of the host.
462
- #
463
- def tcp_ports
464
- each_tcp_port.to_a
465
- end
466
-
467
- #
468
- # Parses the UDP ports of the host.
469
- #
470
- # @yield [port]
471
- # Each UDP port of the host.
472
- #
473
- # @yieldparam [Port] port
474
- # An UDP scanned port of the host.
475
- #
476
- # @return [Host, Enumerator]
477
- # The host.
478
- # If no block was given, an enumerator will be returned.
479
- #
480
- def each_udp_port
481
- return enum_for(__method__) unless block_given?
482
-
483
- @node.xpath("ports/port[@protocol='udp']").each do |port|
484
- yield Port.new(port)
485
- end
486
-
487
- return self
488
- end
489
-
490
- #
491
- # Parses the UDP ports of the host.
492
- #
493
- # @return [Array<Port>]
494
- # The UDP ports of the host.
495
- #
496
- def udp_ports
497
- each_udp_port.to_a
498
- end
499
-
500
- #
501
- # Parses the open ports of the host.
502
- #
503
- # @see each_open_port
504
- #
505
- def each(&block)
506
- each_open_port(&block)
507
- end
508
-
509
- #
510
- # The output from the NSE scripts ran against the host.
511
- #
512
- # @return [Hash{String => String}]
513
- # The NSE script names and output.
514
- #
515
- # @since 0.3.0
516
- #
517
- # @deprecated Use {#host_script} instead.
518
- #
519
- def scripts
520
- if host_script
521
- host_script.scripts
522
- else
523
- {}
524
- end
525
- end
526
-
527
- #
528
- # The NSE scripts ran against the host.
529
- #
530
- # @return [HostScript, nil]
531
- # Contains the host script output and data.
532
- #
533
- # @since 0.9.0
534
- #
535
- def host_script
536
- @host_script ||= if (hostscript = @node.at_xpath('hostscript'))
537
- HostScript.new(hostscript)
538
- end
539
- end
540
-
541
- #
542
- # Parses the traceroute information, if present.
543
- #
544
- # @yield [traceroute]
545
- # If a block is given, it will be passed the traceroute information.
546
- #
547
- # @yieldparam [Traceroute] traceroute
548
- # The traceroute information.
549
- #
550
- # @return [Traceroute]
551
- # The traceroute information.
552
- #
553
- # @since 0.7.0
554
- #
555
- def traceroute
556
- @traceroute ||= if (trace = @node.at_xpath('trace'))
557
- Traceroute.new(trace)
558
- end
559
-
560
- yield @traceroute if (@traceroute && block_given?)
561
- return @traceroute
562
- end
563
-
564
- #
565
- # Converts the host to a String.
566
- #
567
- # @return [String]
568
- # The hostname or address of the host.
569
- #
570
- # @see address
571
- #
572
- def to_s
573
- (hostname || address).to_s
574
- end
575
-
576
- #
577
- # Inspects the host.
578
- #
579
- # @return [String]
580
- # The inspected host.
581
- #
582
- def inspect
583
- "#<#{self.class}: #{self}>"
584
- end
585
-
586
- end
587
- end
@@ -1,18 +0,0 @@
1
- require 'nmap/scripts'
2
-
3
- module Nmap
4
- #
5
- # Represents the `hostscript` element.
6
- #
7
- # @since 0.9.0
8
- #
9
- class HostScript
10
-
11
- include Scripts
12
-
13
- def initialize(node)
14
- @node = node
15
- end
16
-
17
- end
18
- end
data/lib/nmap/hostname.rb DELETED
@@ -1,42 +0,0 @@
1
- module Nmap
2
- #
3
- # Represents a hostname.
4
- #
5
- # @since 0.7.0
6
- #
7
- class Hostname < Struct.new(:type, :name)
8
-
9
- #
10
- # Determines if the hostname was specified by the user.
11
- #
12
- # @return [Boolean]
13
- #
14
- # @since 0.8.0
15
- #
16
- def user?
17
- self.type == 'user'
18
- end
19
-
20
- #
21
- # Determines if the hostname is a DNS `PTR`.
22
- #
23
- # @return [Boolean]
24
- #
25
- # @since 0.8.0
26
- #
27
- def ptr?
28
- self.type == 'PTR'
29
- end
30
-
31
- #
32
- # Converts the hostname to a String.
33
- #
34
- # @return [String]
35
- # The name of the host.
36
- #
37
- def to_s
38
- self.name.to_s
39
- end
40
-
41
- end
42
- end
@@ -1,24 +0,0 @@
1
- require 'nmap/sequence'
2
-
3
- module Nmap
4
- #
5
- # Represents an IP ID.
6
- #
7
- # @since 0.5.0
8
- #
9
- class IpIdSequence < Sequence
10
-
11
- #
12
- # Converts the IpidSequence class to a String.
13
- #
14
- # @return [String]
15
- # The String form of the object.
16
- #
17
- # @since 0.5.0
18
- #
19
- def to_s
20
- "description=#{description.inspect} values=#{values.inspect}"
21
- end
22
-
23
- end
24
- end