ruby-nmap 1.0.1 → 1.0.2
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/ChangeLog.md +8 -0
- data/lib/nmap/command.rb +54 -17
- data/lib/nmap/version.rb +1 -1
- data/lib/nmap/xml/os.rb +1 -1
- data/ruby-nmap.gemspec +1 -0
- data/spec/command_spec.rb +507 -23
- metadata +9 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d68c401c750d115bbd1dbe2d660702749ca20444012e5ef9f06fae022d13029d
|
4
|
+
data.tar.gz: 7909d00c750adbfddb72ede9e50e298d1c3a39803c8f9075bf174bb875d4ae5c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 746169835110421deadef68c804a225b6c7fc4a1b33436deadbf22013b8113ffc48c3edda145a9ff51c5f1d1cb782b4a174baa6b64cc673baa90cd354b44615b
|
7
|
+
data.tar.gz: 42f3be8d68f03624920cd86d752bb525eb0ba66aebea2915a7ee516c2c5ce92b4abbd8a8cbc55072fa91c48b5e8455dcee1ef271324183bae44e44348e8b3f44
|
data/ChangeLog.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
### 1.0.2 / 2023-09-01
|
2
|
+
|
3
|
+
#### Nmap::Command
|
4
|
+
|
5
|
+
* Fixed a typo in the `--unprivileged` option mapping.
|
6
|
+
* Improved validations for port number, service name, port range, and
|
7
|
+
port list String values.
|
8
|
+
|
1
9
|
### 1.0.1 / 2022-12-12
|
2
10
|
|
3
11
|
* Fixed an infinite loop in {Nmap::XML::Script#parse_tables}. (@myztique)
|
data/lib/nmap/command.rb
CHANGED
@@ -185,17 +185,23 @@ module Nmap
|
|
185
185
|
#
|
186
186
|
class Command < CommandMapper::Command
|
187
187
|
|
188
|
+
#
|
189
|
+
# Represents a port number.
|
188
190
|
#
|
189
191
|
# @api private
|
190
192
|
#
|
191
193
|
class Port < CommandMapper::Types::Num
|
192
194
|
|
193
|
-
|
195
|
+
# Regular expression that validates a port number.
|
196
|
+
PORT_NUMBER_REGEXP = /[1-9][0-9]{0,3}|[1-5][0-9][0-9][0-9][0-9]|6[0-4][0-9][0-9][0-9]|65[0-4][0-9][0-9]|655[0-2][0-9]|6553[0-5]/
|
194
197
|
|
195
|
-
|
198
|
+
# Regular expression that validates a service name.
|
199
|
+
SERVICE_NAME_REGEXP = /[A-Za-z][A-Za-z0-9]*(?:[\/_-][A-Za-z0-9]+)*\*?/
|
196
200
|
|
201
|
+
# Regular expression that validates either a port number or service name.
|
197
202
|
PORT_REGEXP = /(?:#{PORT_NUMBER_REGEXP}|#{SERVICE_NAME_REGEXP})/
|
198
203
|
|
204
|
+
# Regular expression that validates either a port number or service name.
|
199
205
|
REGEXP = /\A#{PORT_REGEXP}\z/
|
200
206
|
|
201
207
|
#
|
@@ -206,22 +212,22 @@ module Nmap
|
|
206
212
|
end
|
207
213
|
|
208
214
|
#
|
209
|
-
# Validates the given value.
|
215
|
+
# Validates the given port number value.
|
210
216
|
#
|
211
217
|
# @param [Object] value
|
218
|
+
# The value to validate.
|
212
219
|
#
|
213
220
|
# @return [true, (false, String)]
|
221
|
+
# Returns true if the value is valid, or `false` and a validation error
|
222
|
+
# message if the value is not compatible.
|
214
223
|
#
|
215
224
|
def validate(value)
|
216
225
|
case value
|
217
226
|
when String
|
218
|
-
|
219
|
-
when /\A#{PORT_NUMBER_REGEXP}\z/
|
220
|
-
super(value)
|
221
|
-
when /\A#{SERVICE_NAME_REGEXP}\z/
|
227
|
+
if value =~ REGEXP
|
222
228
|
return true
|
223
229
|
else
|
224
|
-
return [false, "must be a port number or service name (#{value.inspect})"]
|
230
|
+
return [false, "must be a valid port number or service name (#{value.inspect})"]
|
225
231
|
end
|
226
232
|
else
|
227
233
|
super(value)
|
@@ -232,8 +238,10 @@ module Nmap
|
|
232
238
|
# Formats the given value.
|
233
239
|
#
|
234
240
|
# @param [Integer, String] value
|
241
|
+
# The port number value to format.
|
235
242
|
#
|
236
243
|
# @return [String]
|
244
|
+
# The formatted port number.
|
237
245
|
#
|
238
246
|
def format(value)
|
239
247
|
case value
|
@@ -246,21 +254,28 @@ module Nmap
|
|
246
254
|
|
247
255
|
end
|
248
256
|
|
257
|
+
#
|
258
|
+
# Represents a port range.
|
249
259
|
#
|
250
260
|
# @api private
|
251
261
|
#
|
252
262
|
class PortRange < Port
|
253
263
|
|
254
|
-
|
264
|
+
# Regular expression to validate either a port or a port range.
|
265
|
+
PORT_RANGE_REGEXP = /(?:#{PORT_NUMBER_REGEXP})?-(?:#{PORT_NUMBER_REGEXP})?|#{PORT_REGEXP}/
|
255
266
|
|
267
|
+
# Regular expression to validate either a port or a port range.
|
256
268
|
REGEXP = /\A#{PORT_RANGE_REGEXP}\z/
|
257
269
|
|
258
270
|
#
|
259
|
-
# Validates the given value.
|
271
|
+
# Validates the given port or port range value.
|
260
272
|
#
|
261
273
|
# @param [Object] value
|
274
|
+
# The port or port range value to validate.
|
262
275
|
#
|
263
276
|
# @return [true, (false, String)]
|
277
|
+
# Returns true if the value is valid, or `false` and a validation error
|
278
|
+
# message if the value is not compatible.
|
264
279
|
#
|
265
280
|
def validate(value)
|
266
281
|
case value
|
@@ -279,22 +294,24 @@ module Nmap
|
|
279
294
|
|
280
295
|
return true
|
281
296
|
when String
|
282
|
-
|
283
|
-
return
|
297
|
+
if value =~ REGEXP
|
298
|
+
return true
|
299
|
+
else
|
300
|
+
return [false, "must be a valid port number, port range, or service name (#{value.inspect})"]
|
284
301
|
end
|
285
|
-
|
286
|
-
return true
|
287
302
|
else
|
288
303
|
super(value)
|
289
304
|
end
|
290
305
|
end
|
291
306
|
|
292
307
|
#
|
293
|
-
# Formats the given value.
|
308
|
+
# Formats the given port or port range value.
|
294
309
|
#
|
295
310
|
# @param [Range, Integer, String] value
|
311
|
+
# The port or port range value to format.
|
296
312
|
#
|
297
313
|
# @return [String]
|
314
|
+
# The formatted port or port range.
|
298
315
|
#
|
299
316
|
def format(value)
|
300
317
|
case value
|
@@ -307,13 +324,17 @@ module Nmap
|
|
307
324
|
|
308
325
|
end
|
309
326
|
|
327
|
+
#
|
328
|
+
# Represents a list of ports or port ranges.
|
310
329
|
#
|
311
330
|
# @api private
|
312
331
|
#
|
313
332
|
class PortRangeList < CommandMapper::Types::List
|
314
333
|
|
334
|
+
# Regular expression for validating a port or port range.
|
315
335
|
PORT_RANGE_REGEXP = PortRange::PORT_RANGE_REGEXP
|
316
336
|
|
337
|
+
# Regular expression for validating an nmap port range.
|
317
338
|
REGEXP = /\A(?:[TUS]:)?#{PORT_RANGE_REGEXP}(?:,(?:[TUS]:)?#{PORT_RANGE_REGEXP})*\z/
|
318
339
|
|
319
340
|
#
|
@@ -327,8 +348,11 @@ module Nmap
|
|
327
348
|
# Validates the given port range list value.
|
328
349
|
#
|
329
350
|
# @param [Object] value
|
351
|
+
# The given port range list value to validate.
|
330
352
|
#
|
331
353
|
# @return [true, (false, String)]
|
354
|
+
# Returns true if the value is valid, or `false` and a validation error
|
355
|
+
# message if the value is not compatible.
|
332
356
|
#
|
333
357
|
def validate(value)
|
334
358
|
case value
|
@@ -371,11 +395,13 @@ module Nmap
|
|
371
395
|
}
|
372
396
|
|
373
397
|
#
|
374
|
-
# Formats the given value.
|
398
|
+
# Formats the given port range list value.
|
375
399
|
#
|
376
400
|
# @param [Hash, Range, String, Integer] value
|
401
|
+
# The port range list value.
|
377
402
|
#
|
378
403
|
# @return [String]
|
404
|
+
# The formatted port range list.
|
379
405
|
#
|
380
406
|
def format(value)
|
381
407
|
case value
|
@@ -399,16 +425,21 @@ module Nmap
|
|
399
425
|
|
400
426
|
end
|
401
427
|
|
428
|
+
#
|
429
|
+
# Represents a list of protocols.
|
402
430
|
#
|
403
431
|
# @api private
|
404
432
|
#
|
405
433
|
ProtocolList = PortRangeList
|
406
434
|
|
435
|
+
#
|
436
|
+
# Represents a unit of time.
|
407
437
|
#
|
408
438
|
# @api private
|
409
439
|
#
|
410
440
|
class Time < CommandMapper::Types::Str
|
411
441
|
|
442
|
+
# Regular expression for validating a unit of time.
|
412
443
|
REGEXP = /\A\d+(?:h|m|s|ms)?\z/
|
413
444
|
|
414
445
|
#
|
@@ -443,6 +474,8 @@ module Nmap
|
|
443
474
|
|
444
475
|
end
|
445
476
|
|
477
|
+
#
|
478
|
+
# Represents a hex string.
|
446
479
|
#
|
447
480
|
# @api private
|
448
481
|
#
|
@@ -478,11 +511,14 @@ module Nmap
|
|
478
511
|
|
479
512
|
end
|
480
513
|
|
514
|
+
#
|
515
|
+
# Represents one or more TCP scan flags.
|
481
516
|
#
|
482
517
|
# @api private
|
483
518
|
#
|
484
519
|
class ScanFlags < CommandMapper::Types::Str
|
485
520
|
|
521
|
+
# Mapping of symbol scan flags to String values.
|
486
522
|
FLAGS = {
|
487
523
|
urg: 'URG',
|
488
524
|
ack: 'ACK',
|
@@ -492,6 +528,7 @@ module Nmap
|
|
492
528
|
fin: 'FIN'
|
493
529
|
}
|
494
530
|
|
531
|
+
# Regular expression to validate the given scan flags.
|
495
532
|
REGEXP = /\A(?:\d+|(?:URG|ACK|PSH|RST|SYN|FIN)+)\z/
|
496
533
|
|
497
534
|
#
|
@@ -752,7 +789,7 @@ module Nmap
|
|
752
789
|
option '--send-eth'
|
753
790
|
option '--send-ip'
|
754
791
|
option '--privileged'
|
755
|
-
option '--
|
792
|
+
option '--unprivileged'
|
756
793
|
option '--release-memory'
|
757
794
|
option '--noninteractive', name: :non_interactive
|
758
795
|
option '-V', name: :version
|
data/lib/nmap/version.rb
CHANGED
data/lib/nmap/xml/os.rb
CHANGED
data/ruby-nmap.gemspec
CHANGED
@@ -20,6 +20,7 @@ Gem::Specification.new do |gem|
|
|
20
20
|
gem.authors = Array(gemspec['authors'])
|
21
21
|
gem.email = gemspec['email']
|
22
22
|
gem.homepage = gemspec['homepage']
|
23
|
+
gem.metadata = gemspec['metadata'] if gemspec['metadata']
|
23
24
|
|
24
25
|
glob = lambda { |patterns| gem.files & Dir[*patterns] }
|
25
26
|
|
data/spec/command_spec.rb
CHANGED
@@ -43,9 +43,9 @@ describe Nmap::Command do
|
|
43
43
|
context "but it's less than 1" do
|
44
44
|
let(:value) { '0' }
|
45
45
|
|
46
|
-
it "must return [false, \"
|
46
|
+
it "must return [false, \"must be a valid port number or service name (...)\"]" do
|
47
47
|
expect(subject.validate(value)).to eq(
|
48
|
-
[false, "
|
48
|
+
[false, "must be a valid port number or service name (#{value.inspect})"]
|
49
49
|
)
|
50
50
|
end
|
51
51
|
end
|
@@ -53,9 +53,9 @@ describe Nmap::Command do
|
|
53
53
|
context "but it's greater than 65535" do
|
54
54
|
let(:value) { '65536' }
|
55
55
|
|
56
|
-
it "must return [false, \"
|
56
|
+
it "must return [false, \"must be a valid port number or service name (...)\"]" do
|
57
57
|
expect(subject.validate(value)).to eq(
|
58
|
-
[false, "
|
58
|
+
[false, "must be a valid port number or service name (#{value.inspect})"]
|
59
59
|
)
|
60
60
|
end
|
61
61
|
end
|
@@ -87,8 +87,10 @@ describe Nmap::Command do
|
|
87
87
|
context "and it starts with digits" do
|
88
88
|
let(:value) { "1ci-smcs" }
|
89
89
|
|
90
|
-
it "must return
|
91
|
-
expect(subject.validate(value)).to
|
90
|
+
it "must return [false, \"must be a valid port number or service name (...)\"]" do
|
91
|
+
expect(subject.validate(value)).to eq(
|
92
|
+
[false, "must be a valid port number or service name (#{value.inspect})"]
|
93
|
+
)
|
92
94
|
end
|
93
95
|
end
|
94
96
|
|
@@ -101,7 +103,7 @@ describe Nmap::Command do
|
|
101
103
|
end
|
102
104
|
|
103
105
|
context "and it contains a '-' character" do
|
104
|
-
let(:value) { "
|
106
|
+
let(:value) { "iphone-sync" }
|
105
107
|
|
106
108
|
it "must return true" do
|
107
109
|
expect(subject.validate(value)).to be(true)
|
@@ -111,9 +113,9 @@ describe Nmap::Command do
|
|
111
113
|
context "but it starts with a '-' character" do
|
112
114
|
let(:value) { "-foo" }
|
113
115
|
|
114
|
-
it "must return [false, \"must be a port number or service name (...)\"]" do
|
116
|
+
it "must return [false, \"must be a valid port number or service name (...)\"]" do
|
115
117
|
expect(subject.validate(value)).to eq(
|
116
|
-
[false, "must be a port number or service name (#{value.inspect})"]
|
118
|
+
[false, "must be a valid port number or service name (#{value.inspect})"]
|
117
119
|
)
|
118
120
|
end
|
119
121
|
end
|
@@ -121,9 +123,9 @@ describe Nmap::Command do
|
|
121
123
|
context "but it ends with a '-' character" do
|
122
124
|
let(:value) { "foo-" }
|
123
125
|
|
124
|
-
it "must return [false, \"must be a port number or service name (...)\"]" do
|
126
|
+
it "must return [false, \"must be a valid port number or service name (...)\"]" do
|
125
127
|
expect(subject.validate(value)).to eq(
|
126
|
-
[false, "must be a port number or service name (#{value.inspect})"]
|
128
|
+
[false, "must be a valid port number or service name (#{value.inspect})"]
|
127
129
|
)
|
128
130
|
end
|
129
131
|
end
|
@@ -139,9 +141,9 @@ describe Nmap::Command do
|
|
139
141
|
context "but it starts with a '_' character" do
|
140
142
|
let(:value) { "_foo" }
|
141
143
|
|
142
|
-
it "must return [false, \"must be a port number or service name (...)\"]" do
|
144
|
+
it "must return [false, \"must be a valid port number or service name (...)\"]" do
|
143
145
|
expect(subject.validate(value)).to eq(
|
144
|
-
[false, "must be a port number or service name (#{value.inspect})"]
|
146
|
+
[false, "must be a valid port number or service name (#{value.inspect})"]
|
145
147
|
)
|
146
148
|
end
|
147
149
|
end
|
@@ -149,9 +151,9 @@ describe Nmap::Command do
|
|
149
151
|
context "but it ends with a '_' character" do
|
150
152
|
let(:value) { "foo_" }
|
151
153
|
|
152
|
-
it "must return [false, \"must be a port number or service name (...)\"]" do
|
154
|
+
it "must return [false, \"must be a valid port number or service name (...)\"]" do
|
153
155
|
expect(subject.validate(value)).to eq(
|
154
|
-
[false, "must be a port number or service name (#{value.inspect})"]
|
156
|
+
[false, "must be a valid port number or service name (#{value.inspect})"]
|
155
157
|
)
|
156
158
|
end
|
157
159
|
end
|
@@ -167,19 +169,19 @@ describe Nmap::Command do
|
|
167
169
|
context "but it starts with a '/' character" do
|
168
170
|
let(:value) { "/foo" }
|
169
171
|
|
170
|
-
it "must return [false, \"must be a port number or service name (...)\"]" do
|
172
|
+
it "must return [false, \"must be a valid port number or service name (...)\"]" do
|
171
173
|
expect(subject.validate(value)).to eq(
|
172
|
-
[false, "must be a port number or service name (#{value.inspect})"]
|
174
|
+
[false, "must be a valid port number or service name (#{value.inspect})"]
|
173
175
|
)
|
174
176
|
end
|
175
177
|
end
|
176
178
|
|
177
|
-
context "but it
|
179
|
+
context "but it ends with a '/' character" do
|
178
180
|
let(:value) { "foo/" }
|
179
181
|
|
180
|
-
it "must return [false, \"must be a port number or service name (...)\"]" do
|
182
|
+
it "must return [false, \"must be a valid port number or service name (...)\"]" do
|
181
183
|
expect(subject.validate(value)).to eq(
|
182
|
-
[false, "must be a port number or service name (#{value.inspect})"]
|
184
|
+
[false, "must be a valid port number or service name (#{value.inspect})"]
|
183
185
|
)
|
184
186
|
end
|
185
187
|
end
|
@@ -191,9 +193,211 @@ describe Nmap::Command do
|
|
191
193
|
describe described_class::PortRange do
|
192
194
|
describe "#validate" do
|
193
195
|
context "when given an Integer value" do
|
196
|
+
let(:value) { 443 }
|
197
|
+
|
198
|
+
it "must return true" do
|
199
|
+
expect(subject.validate(value)).to be(true)
|
200
|
+
end
|
201
|
+
|
202
|
+
context "but it's less than 1" do
|
203
|
+
let(:value) { 0 }
|
204
|
+
|
205
|
+
it "must return [false, \"(...) not within the range of acceptable values (1..65535)\"]" do
|
206
|
+
expect(subject.validate(value)).to eq(
|
207
|
+
[false, "(#{value.inspect}) not within the range of acceptable values (1..65535)"]
|
208
|
+
)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
context "but it's greater than 65535" do
|
213
|
+
let(:value) { 65536 }
|
214
|
+
|
215
|
+
it "must return [false, \"(...) not within the range of acceptable values (1..65535)\"]" do
|
216
|
+
expect(subject.validate(value)).to eq(
|
217
|
+
[false, "(#{value.inspect}) not within the range of acceptable values (1..65535)"]
|
218
|
+
)
|
219
|
+
end
|
220
|
+
end
|
194
221
|
end
|
195
222
|
|
196
223
|
context "when given a String value" do
|
224
|
+
context "and it's a number" do
|
225
|
+
let(:value) { '443' }
|
226
|
+
|
227
|
+
it "must return true" do
|
228
|
+
expect(subject.validate(value)).to be(true)
|
229
|
+
end
|
230
|
+
|
231
|
+
context "but it's less than 1" do
|
232
|
+
let(:value) { '0' }
|
233
|
+
|
234
|
+
it "must return [false, \"must be a valid port number, port range, or service name (...)\"]" do
|
235
|
+
expect(subject.validate(value)).to eq(
|
236
|
+
[false, "must be a valid port number, port range, or service name (#{value.inspect})"]
|
237
|
+
)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
context "but it's greater than 65535" do
|
242
|
+
let(:value) { '65536' }
|
243
|
+
|
244
|
+
it "must return [false, \"(...) not within the range of acceptable values (1..65535)\"]" do
|
245
|
+
expect(subject.validate(value)).to eq(
|
246
|
+
[false, "must be a valid port number, port range, or service name (#{value.inspect})"]
|
247
|
+
)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
context "and it's a range of two numbers" do
|
253
|
+
let(:value) { "1-1024" }
|
254
|
+
|
255
|
+
it "must return true" do
|
256
|
+
expect(subject.validate(value)).to be(true)
|
257
|
+
end
|
258
|
+
|
259
|
+
context "but the first number is omitted" do
|
260
|
+
let(:value) { "-1024" }
|
261
|
+
|
262
|
+
it "must return true" do
|
263
|
+
expect(subject.validate(value)).to be(true)
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
context "but the last number is omitted" do
|
268
|
+
let(:value) { "1-" }
|
269
|
+
|
270
|
+
it "must return true" do
|
271
|
+
expect(subject.validate(value)).to be(true)
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
context "and it's a service name" do
|
277
|
+
let(:value) { "http" }
|
278
|
+
|
279
|
+
it "must return true" do
|
280
|
+
expect(subject.validate(value)).to be(true)
|
281
|
+
end
|
282
|
+
|
283
|
+
context "and it ends with a '*' character" do
|
284
|
+
let(:value) { "http*" }
|
285
|
+
|
286
|
+
it "must return true" do
|
287
|
+
expect(subject.validate(value)).to be(true)
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
context "and it contains uppercase letters" do
|
292
|
+
let(:value) { "XmlIpcRegSvc" }
|
293
|
+
|
294
|
+
it "must return true" do
|
295
|
+
expect(subject.validate(value)).to be(true)
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
context "and it starts with digits" do
|
300
|
+
let(:value) { "1ci-smcs" }
|
301
|
+
|
302
|
+
it "must return [false, \"must be a valid port number, port range, or service name (...)\"]" do
|
303
|
+
expect(subject.validate(value)).to eq(
|
304
|
+
[false, "must be a valid port number, port range, or service name (#{value.inspect})"]
|
305
|
+
)
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
context "and it contains digits" do
|
310
|
+
let(:value) { "neo4j" }
|
311
|
+
|
312
|
+
it "must return true" do
|
313
|
+
expect(subject.validate(value)).to be(true)
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
context "and it contains a '-' character" do
|
318
|
+
let(:value) { "iphone-sync" }
|
319
|
+
|
320
|
+
it "must return true" do
|
321
|
+
expect(subject.validate(value)).to be(true)
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
context "but it starts with a '-' character" do
|
326
|
+
let(:value) { "-foo" }
|
327
|
+
|
328
|
+
it "must return [false, \"must be a valid port number, port range, or service name (...)\"]" do
|
329
|
+
expect(subject.validate(value)).to eq(
|
330
|
+
[false, "must be a valid port number, port range, or service name (#{value.inspect})"]
|
331
|
+
)
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
context "but it ends with a '-' character" do
|
336
|
+
let(:value) { "foo-" }
|
337
|
+
|
338
|
+
it "must return [false, \"must be a valid port number, port range, or service name (...)\"]" do
|
339
|
+
expect(subject.validate(value)).to eq(
|
340
|
+
[false, "must be a valid port number, port range, or service name (#{value.inspect})"]
|
341
|
+
)
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
context "and it contains a '_' character" do
|
346
|
+
let(:value) { "kerberos_master" }
|
347
|
+
|
348
|
+
it "must return true" do
|
349
|
+
expect(subject.validate(value)).to be(true)
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
context "but it starts with a '_' character" do
|
354
|
+
let(:value) { "_foo" }
|
355
|
+
|
356
|
+
it "must return [false, \"must be a valid port number, port range, or service name (...)\"]" do
|
357
|
+
expect(subject.validate(value)).to eq(
|
358
|
+
[false, "must be a valid port number, port range, or service name (#{value.inspect})"]
|
359
|
+
)
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
context "but it ends with a '_' character" do
|
364
|
+
let(:value) { "foo_" }
|
365
|
+
|
366
|
+
it "must return [false, \"must be a valid port number, port range, or service name (...)\"]" do
|
367
|
+
expect(subject.validate(value)).to eq(
|
368
|
+
[false, "must be a valid port number, port range, or service name (#{value.inspect})"]
|
369
|
+
)
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
context "and it contain's a '/' character" do
|
374
|
+
let(:value) { "cl/1" }
|
375
|
+
|
376
|
+
it "must return true" do
|
377
|
+
expect(subject.validate(value)).to be(true)
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
context "but it starts with a '/' character" do
|
382
|
+
let(:value) { "/foo" }
|
383
|
+
|
384
|
+
it "must return [false, \"must be a valid port number, port range, or service name (...)\"]" do
|
385
|
+
expect(subject.validate(value)).to eq(
|
386
|
+
[false, "must be a valid port number, port range, or service name (#{value.inspect})"]
|
387
|
+
)
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
context "but it starts with a '/' character" do
|
392
|
+
let(:value) { "foo/" }
|
393
|
+
|
394
|
+
it "must return [false, \"must be a valid port number, port range, or service name (...)\"]" do
|
395
|
+
expect(subject.validate(value)).to eq(
|
396
|
+
[false, "must be a valid port number, port range, or service name (#{value.inspect})"]
|
397
|
+
)
|
398
|
+
end
|
399
|
+
end
|
400
|
+
end
|
197
401
|
end
|
198
402
|
|
199
403
|
context "when given a Range of port numbers" do
|
@@ -226,12 +430,292 @@ describe Nmap::Command do
|
|
226
430
|
|
227
431
|
describe described_class::PortRangeList do
|
228
432
|
describe "#validate" do
|
229
|
-
context "when given
|
433
|
+
context "when given an Integer value" do
|
230
434
|
let(:value) { 443 }
|
231
435
|
|
232
436
|
it "must return true" do
|
233
437
|
expect(subject.validate(value)).to be(true)
|
234
438
|
end
|
439
|
+
|
440
|
+
context "but it's less than 1" do
|
441
|
+
let(:value) { 0 }
|
442
|
+
|
443
|
+
it "must return [false, \"element (...) not within the range of acceptable values (1..65535)\"]" do
|
444
|
+
expect(subject.validate(value)).to eq(
|
445
|
+
[false, "element (#{value.inspect}) not within the range of acceptable values (1..65535)"]
|
446
|
+
)
|
447
|
+
end
|
448
|
+
end
|
449
|
+
|
450
|
+
context "but it's greater than 65535" do
|
451
|
+
let(:value) { 65536 }
|
452
|
+
|
453
|
+
it "must return [false, \"element (...) not within the range of acceptable values (1..65535)\"]" do
|
454
|
+
expect(subject.validate(value)).to eq(
|
455
|
+
[false, "element (#{value.inspect}) not within the range of acceptable values (1..65535)"]
|
456
|
+
)
|
457
|
+
end
|
458
|
+
end
|
459
|
+
end
|
460
|
+
|
461
|
+
context "when given a String value" do
|
462
|
+
context "and it's a number" do
|
463
|
+
let(:value) { '443' }
|
464
|
+
|
465
|
+
it "must return true" do
|
466
|
+
expect(subject.validate(value)).to be(true)
|
467
|
+
end
|
468
|
+
|
469
|
+
context "but it's less than 1" do
|
470
|
+
let(:value) { '0' }
|
471
|
+
|
472
|
+
it "must return [false, \"not a valid port range list (...)\"]" do
|
473
|
+
expect(subject.validate(value)).to eq(
|
474
|
+
[false, "not a valid port range list (#{value.inspect})"]
|
475
|
+
)
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
479
|
+
context "but it's greater than 65535" do
|
480
|
+
let(:value) { '65536' }
|
481
|
+
|
482
|
+
it "must return [false, \"(...) not within the range of acceptable values (1..65535)\"]" do
|
483
|
+
expect(subject.validate(value)).to eq(
|
484
|
+
[false, "not a valid port range list (#{value.inspect})"]
|
485
|
+
)
|
486
|
+
end
|
487
|
+
end
|
488
|
+
end
|
489
|
+
|
490
|
+
context "and it's a range of two numbers" do
|
491
|
+
let(:value) { "1-1024" }
|
492
|
+
|
493
|
+
it "must return true" do
|
494
|
+
expect(subject.validate(value)).to be(true)
|
495
|
+
end
|
496
|
+
|
497
|
+
context "but the first number is omitted" do
|
498
|
+
let(:value) { "-1024" }
|
499
|
+
|
500
|
+
it "must return true" do
|
501
|
+
expect(subject.validate(value)).to be(true)
|
502
|
+
end
|
503
|
+
end
|
504
|
+
|
505
|
+
context "but the last number is omitted" do
|
506
|
+
let(:value) { "1-" }
|
507
|
+
|
508
|
+
it "must return true" do
|
509
|
+
expect(subject.validate(value)).to be(true)
|
510
|
+
end
|
511
|
+
end
|
512
|
+
end
|
513
|
+
|
514
|
+
context "and it's a service name" do
|
515
|
+
let(:value) { "http" }
|
516
|
+
|
517
|
+
it "must return true" do
|
518
|
+
expect(subject.validate(value)).to be(true)
|
519
|
+
end
|
520
|
+
|
521
|
+
context "and it ends with a '*' character" do
|
522
|
+
let(:value) { "http*" }
|
523
|
+
|
524
|
+
it "must return true" do
|
525
|
+
expect(subject.validate(value)).to be(true)
|
526
|
+
end
|
527
|
+
end
|
528
|
+
|
529
|
+
context "and it contains uppercase letters" do
|
530
|
+
let(:value) { "XmlIpcRegSvc" }
|
531
|
+
|
532
|
+
it "must return true" do
|
533
|
+
expect(subject.validate(value)).to be(true)
|
534
|
+
end
|
535
|
+
end
|
536
|
+
|
537
|
+
context "and it starts with digits" do
|
538
|
+
let(:value) { "1ci-smcs" }
|
539
|
+
|
540
|
+
it "must return [false, \"not a valid port range list (...)\"]" do
|
541
|
+
expect(subject.validate(value)).to eq(
|
542
|
+
[false, "not a valid port range list (#{value.inspect})"]
|
543
|
+
)
|
544
|
+
end
|
545
|
+
end
|
546
|
+
|
547
|
+
context "and it contains digits" do
|
548
|
+
let(:value) { "neo4j" }
|
549
|
+
|
550
|
+
it "must return true" do
|
551
|
+
expect(subject.validate(value)).to be(true)
|
552
|
+
end
|
553
|
+
end
|
554
|
+
|
555
|
+
context "and it contains a '-' character" do
|
556
|
+
let(:value) { "iphone-sync" }
|
557
|
+
|
558
|
+
it "must return true" do
|
559
|
+
expect(subject.validate(value)).to be(true)
|
560
|
+
end
|
561
|
+
end
|
562
|
+
|
563
|
+
context "but it starts with a '-' character" do
|
564
|
+
let(:value) { "-foo" }
|
565
|
+
|
566
|
+
it "must return [false, \"not a valid port range list (...)\"]" do
|
567
|
+
expect(subject.validate(value)).to eq(
|
568
|
+
[false, "not a valid port range list (#{value.inspect})"]
|
569
|
+
)
|
570
|
+
end
|
571
|
+
end
|
572
|
+
|
573
|
+
context "but it ends with a '-' character" do
|
574
|
+
let(:value) { "foo-" }
|
575
|
+
|
576
|
+
it "must return [false, \"not a valid port range list (...)\"]" do
|
577
|
+
expect(subject.validate(value)).to eq(
|
578
|
+
[false, "not a valid port range list (#{value.inspect})"]
|
579
|
+
)
|
580
|
+
end
|
581
|
+
end
|
582
|
+
|
583
|
+
context "and it contains a '_' character" do
|
584
|
+
let(:value) { "kerberos_master" }
|
585
|
+
|
586
|
+
it "must return true" do
|
587
|
+
expect(subject.validate(value)).to be(true)
|
588
|
+
end
|
589
|
+
end
|
590
|
+
|
591
|
+
context "but it starts with a '_' character" do
|
592
|
+
let(:value) { "_foo" }
|
593
|
+
|
594
|
+
it "must return [false, \"not a valid port range list (...)\"]" do
|
595
|
+
expect(subject.validate(value)).to eq(
|
596
|
+
[false, "not a valid port range list (#{value.inspect})"]
|
597
|
+
)
|
598
|
+
end
|
599
|
+
end
|
600
|
+
|
601
|
+
context "but it ends with a '_' character" do
|
602
|
+
let(:value) { "foo_" }
|
603
|
+
|
604
|
+
it "must return [false, \"not a valid port range list (...)\"]" do
|
605
|
+
expect(subject.validate(value)).to eq(
|
606
|
+
[false, "not a valid port range list (#{value.inspect})"]
|
607
|
+
)
|
608
|
+
end
|
609
|
+
end
|
610
|
+
|
611
|
+
context "and it contain's a '/' character" do
|
612
|
+
let(:value) { "cl/1" }
|
613
|
+
|
614
|
+
it "must return true" do
|
615
|
+
expect(subject.validate(value)).to be(true)
|
616
|
+
end
|
617
|
+
end
|
618
|
+
|
619
|
+
context "but it starts with a '/' character" do
|
620
|
+
let(:value) { "/foo" }
|
621
|
+
|
622
|
+
it "must return [false, \"not a valid port range list (...)\"]" do
|
623
|
+
expect(subject.validate(value)).to eq(
|
624
|
+
[false, "not a valid port range list (#{value.inspect})"]
|
625
|
+
)
|
626
|
+
end
|
627
|
+
end
|
628
|
+
|
629
|
+
context "but it starts with a '/' character" do
|
630
|
+
let(:value) { "foo/" }
|
631
|
+
|
632
|
+
it "must return [false, \"not a valid port range list (...)\"]" do
|
633
|
+
expect(subject.validate(value)).to eq(
|
634
|
+
[false, "not a valid port range list (#{value.inspect})"]
|
635
|
+
)
|
636
|
+
end
|
637
|
+
end
|
638
|
+
end
|
639
|
+
|
640
|
+
context "and it's a comma separated list of port numbers" do
|
641
|
+
let(:value) { "1,22,80,443" }
|
642
|
+
|
643
|
+
it "must return true" do
|
644
|
+
expect(subject.validate(value)).to be(true)
|
645
|
+
end
|
646
|
+
end
|
647
|
+
|
648
|
+
context "and it's a comma separated list of port ranges" do
|
649
|
+
let(:value) { "1-22,8000-9000" }
|
650
|
+
|
651
|
+
it "must return true" do
|
652
|
+
expect(subject.validate(value)).to be(true)
|
653
|
+
end
|
654
|
+
end
|
655
|
+
|
656
|
+
context "and it's a comma separated list of port numbers and ranges" do
|
657
|
+
let(:value) { "1-22,80,443,8000-9000" }
|
658
|
+
|
659
|
+
it "must return true" do
|
660
|
+
expect(subject.validate(value)).to be(true)
|
661
|
+
end
|
662
|
+
end
|
663
|
+
|
664
|
+
context "and it's a range of two numbers, with a protocol prefix" do
|
665
|
+
let(:value) { "T:1-1024" }
|
666
|
+
|
667
|
+
it "must return true" do
|
668
|
+
expect(subject.validate(value)).to be(true)
|
669
|
+
end
|
670
|
+
|
671
|
+
context "but the first number is omitted" do
|
672
|
+
let(:value) { "T:-1024" }
|
673
|
+
|
674
|
+
it "must return true" do
|
675
|
+
expect(subject.validate(value)).to be(true)
|
676
|
+
end
|
677
|
+
end
|
678
|
+
|
679
|
+
context "but the last number is omitted" do
|
680
|
+
let(:value) { "T:1-" }
|
681
|
+
|
682
|
+
it "must return true" do
|
683
|
+
expect(subject.validate(value)).to be(true)
|
684
|
+
end
|
685
|
+
end
|
686
|
+
end
|
687
|
+
|
688
|
+
context "and it's a service name, with a protocol prefix" do
|
689
|
+
let(:value) { "T:http" }
|
690
|
+
|
691
|
+
it "must return true" do
|
692
|
+
expect(subject.validate(value)).to be(true)
|
693
|
+
end
|
694
|
+
end
|
695
|
+
|
696
|
+
context "and it's a comma separated list of port numbers, with protocol prefixes" do
|
697
|
+
let(:value) { "T:1,T:22,T:80,T:443,U:9000" }
|
698
|
+
|
699
|
+
it "must return true" do
|
700
|
+
expect(subject.validate(value)).to be(true)
|
701
|
+
end
|
702
|
+
end
|
703
|
+
|
704
|
+
context "and it's a comma separated list of port ranges, with protocol prefixes" do
|
705
|
+
let(:value) { "T:1-22,U:8000-9000" }
|
706
|
+
|
707
|
+
it "must return true" do
|
708
|
+
expect(subject.validate(value)).to be(true)
|
709
|
+
end
|
710
|
+
end
|
711
|
+
|
712
|
+
context "and it's a comma separated list of port numbers and ranges, with protocol prefixes" do
|
713
|
+
let(:value) { "T:1-22,T:80,T:443,U:8000-9000" }
|
714
|
+
|
715
|
+
it "must return true" do
|
716
|
+
expect(subject.validate(value)).to be(true)
|
717
|
+
end
|
718
|
+
end
|
235
719
|
end
|
236
720
|
|
237
721
|
context "when given a Range of port numbers" do
|
@@ -319,9 +803,9 @@ describe Nmap::Command do
|
|
319
803
|
{tcp: [1,2,3,4], udp: [1, bad_port, 3], sctp: [1,2,3,4]}
|
320
804
|
end
|
321
805
|
|
322
|
-
it "must return [false, \"element
|
806
|
+
it "must return [false, \"element element must be a valid port number, port range, or service name (...)\"]" do
|
323
807
|
expect(subject.validate(value)).to eq(
|
324
|
-
[false, "element
|
808
|
+
[false, "element must be a valid port number, port range, or service name (#{bad_port.inspect})"]
|
325
809
|
)
|
326
810
|
end
|
327
811
|
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: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Postmodern
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-09-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -145,7 +145,12 @@ files:
|
|
145
145
|
homepage: https://github.com/postmodern/ruby-nmap#readme
|
146
146
|
licenses:
|
147
147
|
- MIT
|
148
|
-
metadata:
|
148
|
+
metadata:
|
149
|
+
documentation_uri: https://rubydoc.info/gems/ruby-nmap
|
150
|
+
source_code_uri: https://github.com/postmodern/ruby-nmap
|
151
|
+
bug_tracker_uri: https://github.com/postmodern/ruby-nmap/issues
|
152
|
+
changelog_uri: https://github.com/postmodern/ruby-nmap/blob/master/ChangeLog.md
|
153
|
+
rubygems_mfa_required: 'true'
|
149
154
|
post_install_message:
|
150
155
|
rdoc_options: []
|
151
156
|
require_paths:
|
@@ -162,7 +167,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
162
167
|
version: '0'
|
163
168
|
requirements:
|
164
169
|
- nmap >= 5.00
|
165
|
-
rubygems_version: 3.
|
170
|
+
rubygems_version: 3.4.10
|
166
171
|
signing_key:
|
167
172
|
specification_version: 4
|
168
173
|
summary: A Ruby API to nmap.
|