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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 10533e46eeeaa57e4cf26c7944e4414ea3921999e31c6aa54d55de225f32494b
4
- data.tar.gz: 65aaebd79d602846dfc6cf0eecbcdef71cb0ae0282fd0d2dab54a3d1db571587
3
+ metadata.gz: d68c401c750d115bbd1dbe2d660702749ca20444012e5ef9f06fae022d13029d
4
+ data.tar.gz: 7909d00c750adbfddb72ede9e50e298d1c3a39803c8f9075bf174bb875d4ae5c
5
5
  SHA512:
6
- metadata.gz: b82ab296170e41097a4eaba98480d1c4715643d6288d33f7626d959ad90c8cc925dee6fdf6654ed84e9bf03db1a4c9847bffac312bff4e4067c0b13af92aa145
7
- data.tar.gz: c6c439fd6e7999116dc61fd4b8713fa862be346c4e0c465dbba4c697363e18acb4985dd22358c2de77585579cb87cd91bbda451996e2b104ede04b23284b91e0
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
- PORT_NUMBER_REGEXP = /\d{1,5}/
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
- SERVICE_NAME_REGEXP = /[A-Za-z0-9]+(?:[\/_-][A-Za-z0-9]+)*\*?/
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
- case value
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
- PORT_RANGE_REGEXP = /(?:#{PORT_REGEXP}|#{PORT_REGEXP}?-#{PORT_REGEXP}?)/
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
- unless value =~ REGEXP
283
- return [false, "not a valid port range (#{value.inspect})"]
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 '--unprivleged'
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
@@ -1,4 +1,4 @@
1
1
  module Nmap
2
2
  # ruby-nmap version
3
- VERSION = '1.0.1'
3
+ VERSION = '1.0.2'
4
4
  end
data/lib/nmap/xml/os.rb CHANGED
@@ -71,7 +71,7 @@ module Nmap
71
71
  def each_match
72
72
  return enum_for(__method__) unless block_given?
73
73
 
74
- @node.xpath("osmatch").map do |osclass|
74
+ @node.xpath("osmatch").each do |osclass|
75
75
  os_match = OSMatch.new(
76
76
  osclass['name'],
77
77
  osclass['accuracy'].to_i
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, \"(...) not within the range of acceptable values (1..65535)\"]" do
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, "(#{value.inspect}) not within the range of acceptable values (1..65535)"]
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, \"(...) not within the range of acceptable values (1..65535)\"]" do
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, "(#{value.inspect}) not within the range of acceptable values (1..65535)"]
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 true" do
91
- expect(subject.validate(value)).to be(true)
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) { "3gpp-cbsp" }
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 starts with a '/' character" do
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 a single port number" do
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 not a valid port range (...)\"]" do
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 not a valid port range (#{bad_port.inspect})"]
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.1
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: 2022-12-13 00:00:00.000000000 Z
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.3.26
170
+ rubygems_version: 3.4.10
166
171
  signing_key:
167
172
  specification_version: 4
168
173
  summary: A Ruby API to nmap.