8291_scanner 1.0.0 → 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: 9c1fbcd809d8e07b1ae613e25b2270a069f2ef2a2ffc58cd7ccfce0c10d689e0
4
- data.tar.gz: 8ec55b9d4cb896149c328e6306a17425bff26571b0baab1714cf9d914f1cd583
3
+ metadata.gz: 3b2c610d2d178592045fa499f7242336739fea9dd064c2fb572f2194b16663e5
4
+ data.tar.gz: dbf44c21d5b52f8ebc9e10a34848b12daa48ff9884bc8d78060379b978f69bca
5
5
  SHA512:
6
- metadata.gz: 03f95da14003fb916106e05ec758e601bb9fdc4e20275a98ce763556a3dbd36dee722e3efbe3db8e2363e80a3e7f4a1684d20e98c5ba400d9e97a62f9d4f8e3b
7
- data.tar.gz: 5a077557feb4db3443fe5889b896c61b9d9b5bf4541e6930860c4075ac85cefe8ef5bd870c7368f841dff3ca7e195cea20ab924fde3d7ed3c8421a07595c08db
6
+ metadata.gz: 7fbe53e33e2f281e961b7b1ae80179d3049cc301ba094f2996613e453c42ba0cebb476d58362606710366a637b80ad823ecbd4cf2f8d14561c847481b19846e6
7
+ data.tar.gz: 5de9242e4d98f4d01c2cb3967e76cc04fa2a287d6db4e6ae05169b9ec5296f2fa70cac8bbc67f8633b85465fb38d8fc33b3a541098afc28c159c3d25d8bc65c0
data/bin/8291_scanner CHANGED
@@ -4,12 +4,12 @@
4
4
 
5
5
  require '8291_scanner/winbox_connection'
6
6
 
7
- if ARGV.length < 1
7
+ if ARGV.empty?
8
8
  puts 'Too few arguments.'
9
9
  puts 'Usage: 8291_scanner host [port]'
10
10
  exit!
11
11
  elsif ARGV.length > 2
12
- puts "Too much arguments."
12
+ puts 'Too much arguments.'
13
13
  puts 'Usage: 8291_scanner host [port]'
14
14
  exit!
15
15
  end
@@ -17,6 +17,6 @@ end
17
17
  host = ARGV[0]
18
18
  port = ARGV[1]&.to_i
19
19
 
20
- connection = (port ? WinboxConnection.new(host, port) : WinboxConnection.new(host))
20
+ connection = (port ? WinboxAPIScanner::WinboxConnection.new(host, port) : WinboxAPIScanner::WinboxConnection.new(host))
21
21
 
22
- puts connection.get_version
22
+ puts connection.request_version
@@ -1,17 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
  # sharable_constant_value: literal
3
3
 
4
- # General Winbox error
5
- class WinboxError < Exception; end
4
+ # Scanner that connects to the Winbox API of Mikrotik's RouterOS and attempts to read the version of the operating system.
5
+ module WinboxAPIScanner
6
+ # General Winbox error
7
+ class WinboxError < StandardError; end
6
8
 
7
- # Error in the connection to the Winbox API
8
- class WinboxConnectionError < Exception; end
9
+ # Error in the connection to the Winbox API
10
+ class WinboxConnectionError < WinboxError; end
9
11
 
10
- # An invalid or unexpected magic number has occurred in the response
11
- class InvalidMagicNumberError < WinboxError; end
12
+ # An invalid or unexpected magic number has occurred in the response
13
+ class InvalidMagicNumberError < WinboxError; end
12
14
 
13
- # A different file was returned than was requested
14
- class FilenameError < WinboxError; end
15
+ # A different file was returned than was requested
16
+ class FilenameError < WinboxError; end
15
17
 
16
- # The list is invalid
17
- class InvalidListError < WinboxError; end
18
+ # The list is invalid
19
+ class InvalidListError < WinboxError; end
20
+ end
@@ -1,98 +1,98 @@
1
1
  # frozen_string_literal: true
2
2
  # sharable_constant_value: literal
3
3
 
4
- # Models a connection to the Winbox API with an underlying TCP connection
5
- class WinboxConnection
6
-
7
- # Reference implementation: https://github.com/tenable/routeros/tree/master/8291_scanner
8
-
9
- require 'socket'
10
- require 'psych'
11
- require_relative 'errors'
12
-
13
- # Initializes a Winbox API connection
14
- #
15
- # @param host [String]
16
- # @param port [Integer]
17
- def initialize(host, port = 8291)
18
- raise ArgumentError, 'Host must be a string' unless host.is_a? String
19
- raise ArgumentError, 'Port must be an integer' unless port.is_a? Integer
20
-
21
- begin
22
- @socket = TCPSocket.new(host, port)
23
- rescue SocketError, EncodingError, EOFError, IO::TimeoutError, Errno::EHOSTUNREACH, Errno::ECONNRESET => e
24
- raise WinboxConnectionError, "Failed to connect to Winbox API: #{e.message}"
4
+ # Scanner that connects to the Winbox API of Mikrotik's RouterOS and attempts to read the version of the operating system.
5
+ module WinboxAPIScanner
6
+ # Models a connection to the Winbox API with an underlying TCP connection
7
+ class WinboxConnection
8
+ # Reference implementation: https://github.com/tenable/routeros/tree/master/8291_scanner
9
+
10
+ require 'socket'
11
+ require 'psych'
12
+ require_relative 'errors'
13
+
14
+ # Initializes a Winbox API connection
15
+ #
16
+ # @param host [String]
17
+ # @param port [Integer]
18
+ def initialize(host, port = 8291)
19
+ raise ArgumentError, 'Host must be a string' unless host.is_a? String
20
+ raise ArgumentError, 'Port must be an integer' unless port.is_a? Integer
21
+
22
+ begin
23
+ @socket = TCPSocket.new(host, port)
24
+ rescue SocketError, EncodingError, EOFError, IO::TimeoutError, Errno::EHOSTUNREACH, Errno::ECONNRESET => e
25
+ raise WinboxConnectionError, "Failed to connect to Winbox API: #{e.message}"
26
+ end
25
27
  end
26
- end
27
28
 
28
- # Fetches the first 128 bytes of a file
29
- #
30
- # @param file [String]
31
- # @return [String]
32
- def old_mproxy_get_file(file)
33
- raise ArgumentError, 'File must be a string' unless file.is_a? String
34
- raise ArgumentError, 'Filename too long' if file.length > 12
29
+ # Fetches the first 128 bytes of a file
30
+ #
31
+ # @param file [String]
32
+ # @return [String]
33
+ def old_mproxy_get_file(file)
34
+ raise ArgumentError, 'File must be a string' unless file.is_a? String
35
+ raise ArgumentError, 'Filename too long' if file.length > 12
35
36
 
36
- # Prepare the file name
37
- file_request = file.ljust(12, "\x00")
37
+ # Prepare the file name
38
+ file_request = file.ljust(12, "\x00")
38
39
 
39
- # Request only the first 128 bytes of the response.
40
- file_request += "\x00\x80\x00\x00\x00\x00"
40
+ # Request only the first 128 bytes of the response.
41
+ file_request += "\x00\x80\x00\x00\x00\x00"
41
42
 
42
- # Create and send request
43
- request = "#{[file_request.length].pack 'C'}\x02#{file_request}"
44
- @socket.send request, 0
45
- @socket.flush
43
+ # Create and send request
44
+ request = "#{[file_request.length].pack 'C'}\x02#{file_request}"
45
+ @socket.send request, 0
46
+ @socket.flush
46
47
 
47
- # Receive short length and first magic number
48
- short_length = @socket.recv(1).unpack('C')[0]
49
- magic_number1 = @socket.recv(1)
50
- raise InvalidMagicNumberError, "Unknown magic number 1 in answer: #{magic_number1.dump}" unless magic_number1 == "\x02"
48
+ # Receive short length and first magic number
49
+ short_length = @socket.recv(1).unpack1('C')
50
+ magic_number1 = @socket.recv(1)
51
+ raise InvalidMagicNumberError, "Unknown magic number 1 in answer: #{magic_number1.dump}" unless magic_number1 == "\x02"
51
52
 
52
- # Receive the name of the file in the response and the second magic number (probably an error code?)
53
- name = @socket.recv(11).rstrip
54
- magic_number2 = @socket.recv 1
55
- raise InvalidMagicNumberError, "Unknown magic number 2 in answer: #{magic_number2.dump}" unless magic_number2 == "\x01"
53
+ # Receive the name of the file in the response and the second magic number (probably an error code?)
54
+ name = @socket.recv(11).rstrip
55
+ magic_number2 = @socket.recv 1
56
+ raise InvalidMagicNumberError, "Unknown magic number 2 in answer: #{magic_number2.dump}" unless magic_number2 == "\x01"
56
57
 
57
- raise FilenameError, 'Returned file is not requested file' unless name == file
58
+ raise FilenameError, 'Returned file is not requested file' unless name == file
58
59
 
59
- long_length = @socket.recv(2).unpack('n')[0]
60
+ long_length = @socket.recv(2).unpack1('n')
60
61
 
61
- magic_number3 = @socket.recv 4
62
- raise InvalidMagicNumberError, "Unknown magic number 3 in answer: #{magic_number3.dump}" unless magic_number3 == "\x00\x00\x00\x00"
62
+ magic_number3 = @socket.recv 4
63
+ raise InvalidMagicNumberError, "Unknown magic number 3 in answer: #{magic_number3.dump}" unless magic_number3 == "\x00\x00\x00\x00"
63
64
 
64
- # Use the short length if possible. If the short length has the maximum value, use the long length.
65
- length = ( short_length == 255 ? long_length : short_length )
65
+ # Use the short length if possible. If the short length has the maximum value, use the long length.
66
+ length = (short_length == 255 ? long_length : short_length)
66
67
 
67
- # Read the answer
68
- buffer = @socket.recv length
68
+ # Read the answer
69
+ buffer = @socket.recv length
69
70
 
70
- # Return the answer
71
- return buffer
72
- rescue SocketError, EncodingError, EOFError, IO::TimeoutError, Errno::EHOSTUNREACH, Errno::ECONNRESET => e
73
- raise WinboxConnectionError, "Failed to connect to Winbox API: #{e.message}"
74
- end
71
+ # Return the answer
72
+ return buffer
73
+ rescue SocketError, EncodingError, EOFError, IO::TimeoutError, Errno::EHOSTUNREACH, Errno::ECONNRESET => e
74
+ raise WinboxConnectionError, "Failed to connect to Winbox API: #{e.message}"
75
+ end
75
76
 
76
- # @return [String]
77
- def get_version
78
- # Receive the first bytes of the list
79
- answer = old_mproxy_get_file('list')
77
+ # @return [String]
78
+ def request_version
79
+ # Receive the first bytes of the list
80
+ answer = old_mproxy_get_file('list')
80
81
 
81
- # Extract the first file information (formatted as JSON) from the response
82
- json_raw = answer[0...answer.index("\n")-1]
82
+ # Extract the first file information (formatted as JSON) from the response
83
+ json_raw = answer[0...(answer.index("\n") - 1)]
83
84
 
84
- raise InvalidListError, 'JSON is empty' if json_raw.empty?
85
+ raise InvalidListError, 'JSON is empty' if json_raw.empty?
85
86
 
86
- # Load the JSON
87
- first_file = Psych.safe_load json_raw
87
+ # Load the JSON
88
+ first_file = Psych.safe_load json_raw
88
89
 
89
- raise InvalidListError, 'List is not JSON' unless first_file.is_a? Hash
90
- raise InvalidListError, 'File does not have a version information' unless first_file['version']
91
-
92
- version = first_file['version']
90
+ raise InvalidListError, 'List is not JSON' unless first_file.is_a? Hash
91
+ raise InvalidListError, 'File does not have a version information' unless first_file['version']
93
92
 
94
- return version
95
- end
93
+ version = first_file['version']
96
94
 
95
+ return version
96
+ end
97
+ end
97
98
  end
98
-
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: 8291_scanner
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marek Küthe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-07-11 00:00:00.000000000 Z
11
+ date: 2024-07-22 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: This tool connects to the Winbox API of Mikrotik's RouterOS and tries
14
14
  to read the operating system version.
@@ -27,7 +27,7 @@ files:
27
27
  - lib/8291_scanner/winbox_connection.rb
28
28
  homepage: https://codeberg.org/mark22k/8291_scanner
29
29
  licenses:
30
- - WTFPL
30
+ - GPL-3.0-or-later
31
31
  metadata:
32
32
  source_code_uri: https://codeberg.org/mark22k/8291_scanner
33
33
  bug_tracker_uri: https://codeberg.org/mark22k/8291_scanner/issues
@@ -47,7 +47,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
47
47
  - !ruby/object:Gem::Version
48
48
  version: '0'
49
49
  requirements: []
50
- rubygems_version: 3.5.15
50
+ rubygems_version: 3.5.11
51
51
  signing_key:
52
52
  specification_version: 4
53
53
  summary: connects to the Winbox API of Mikrotik's RouterOS and tries to read the operating