NETRAVE/lib/utils/utilities.rb
VetheonGames f8ea01ed1b Implement Initial System Setup and Packet Capture
1. Initial System Setup:
   - Implemented a first run initialization process that guides the user through setting up the necessary environment variables.
   - Created a method to securely ask for the user's sudo password, test it, and store it in an encrypted form in an environment variable for use during the first run setup process.
   - Added a method to clear the sudo password from memory and the environment variables at the end of the first run setup process.

2. Packet Capture:
   - Created a PacketCapture class that uses the PCAPRUB library to capture packets from a specified network interface.
   - Refactored the packet capture process to add each captured packet to a Redis queue for further processing, instead of processing the packets directly.
   - Removed the manual packet dissection from the packet capture process, as this will be handled by the workers.

3. Networking Setup:
   - Created a NetworkingGenie class to handle the setup of the necessary networking components.
   - Added methods to identify the main network interface, create a dummy network interface, and set up traffic mirroring from the main interface to the dummy interface.

4. Logging:
   - Implemented logging for all major actions and errors throughout the system.

5. General Refactoring and Code Cleanup:
   - Refactored and cleaned up various parts of the code to improve readability and maintainability.
   - Fixed various minor bugs and issues.

This commit lays the groundwork for the packet processing workers and the orchestrator that will manage them. The next steps will be to implement these components and integrate them with the existing system.
2023-06-29 22:36:18 -06:00

145 lines
4.3 KiB
Ruby

# frozen_string_literal: true
require 'securerandom'
require 'digest'
require 'base64'
require 'openssl'
require 'sudo'
# Utiltiies Module
module Utilities
# Converts speed from Gbps to Mbps if necessary
def convert_speed_to_mbps(speed)
return nil unless speed.is_a?(String) && speed.downcase.match?(/\A\d+(gbps|mbps)\z/i)
# Extract the numeric part and the unit from the speed
numeric_speed, unit = speed.downcase.match(/(\d+)(gbps|mbps)/i).captures
# Convert the numeric part to an integer
numeric_speed = numeric_speed.to_i
# If the unit is 'gbps', multiply the numeric part by 1000
numeric_speed *= 1000 if unit == 'gbps'
numeric_speed
end
# Converts an array of services into a hash
def services_to_hash(services)
services_hash = {}
services.each { |service| services_hash[service] = true }
services_hash
end
# Calculates total bandwidth from uplink and downlink speeds
def calculate_total_bandwidth(uplink_speed, downlink_speed)
uplink_speed + downlink_speed
end
def generate_key
Base64.encode64(SecureRandom.bytes(32)).chomp
end
def encrypt_string_chacha20(data, key)
return nil if data.nil? || key.nil?
cipher = OpenSSL::Cipher.new('chacha20')
cipher.encrypt
cipher.key = Base64.decode64(key) # Decode the key from Base64
encrypted_data = cipher.update(data) + cipher.final
Base64.encode64(encrypted_data).chomp
rescue OpenSSL::Cipher::CipherError => e
@loggman.log_error("Failed to encrypt data: #{e.message}")
nil
end
def decrypt_string_chacha20(encrypted_data, key) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
return nil if encrypted_data.nil? || key.nil?
cipher = OpenSSL::Cipher.new('chacha20')
cipher.decrypt
cipher.key = Base64.decode64(key) # Decode the key from Base64
decrypted_data = cipher.update(Base64.decode64(encrypted_data)) + cipher.final
# Check if the decrypted data is valid ASCII
decrypted_data.force_encoding('UTF-8')
if decrypted_data.valid_encoding?
decrypted_data
else
@loggman.log_error("Decrypted data is not valid ASCII: #{decrypted_data.inspect}")
nil
end
rescue OpenSSL::Cipher::CipherError => e
@loggman.log_error("Failed to decrypt data: #{e.message}")
nil
end
def display_alert(message, severity) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
case severity
when :info
Curses.attron(Curses.color_pair(1)) # Blue color
when :warning
Curses.attron(Curses.color_pair(3)) # Yellow color
when :error
Curses.attron(Curses.color_pair(2)) # Red color
end
Curses.setpos(Curses.lines - 1, 0)
Curses.addstr(message)
Curses.refresh
Thread.new do
sleep(5) # Pause for 5 seconds
# Clear the alert
Curses.setpos(Curses.lines - 1, 0)
Curses.clrtoeol
Curses.refresh
end
Curses.attroff(Curses.color_pair(1)) if severity == :info
Curses.attroff(Curses.color_pair(3)) if severity == :warning
Curses.attroff(Curses.color_pair(2)) if severity == :error
end
def ask_for_sudo(logger)
@loggman = logger
@loggman.log_info('Asking for sudo password...')
Curses.addstr('Please enter your sudo password: ')
sudo_password = DCI.catch_input(true)
@loggman.log_info('Sudo password received.')
sudo_password
end
def test_and_deescalate_sudo(sudo_password)
# Run a simple command with sudo privileges
Sudo::Wrapper.run('ls', password: sudo_password)
# Invalidate the user's cached credentials
Sudo::Wrapper.run('sudo -k', password: sudo_password)
# Encrypt the sudo password and store it in an environment variable
encrypted_sudo_password = encrypt_string_chacha20(sudo_password, @secret_key)
ENV['SPW'] = encrypted_sudo_password
true
rescue Sudo::Wrapper::InvalidPassword
false
end
def clear_sudo_password
# Retrieve the encrypted sudo password from the environment variable
encrypted_sudo_password = ENV['SPW']
# Decrypt the sudo password
sudo_password = decrypt_string_chacha20(encrypted_sudo_password, @secret_key)
# Clear the sudo password from memory
sudo_password.replace(' ' * sudo_password.length)
# Remove the encrypted sudo password from the environment variables
ENV.delete('SPW')
end
end