8291_scanner 1.0.0 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
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