diff --git a/TODO.md b/TODO.md index 2295ef6..e265407 100644 --- a/TODO.md +++ b/TODO.md @@ -14,10 +14,10 @@ - [ ] Develop the user interface for each module. - [ ] Create a system for managing and updating modules. - [x] Implement the database connection and management system. -- [ ] Create a system for handling errors and exceptions. -- [ ] Implement a logging system for tracking and debugging issues. +- [x] Create a system for handling errors and exceptions. +- [x] Implement a logging system for tracking and debugging issues. - [ ] Develop a system for managing user settings and preferences. -- [ ] Implement security measures to protect user data and system integrity. +- [x] Implement security measures to protect user data and system integrity. - [ ] Develop a system for automated updates and patches. - [ ] Implement a system for user feedback and suggestions. diff --git a/lib/utils/networking_genie.rb b/lib/utils/networking_genie.rb index d5d9b58..9597410 100644 --- a/lib/utils/networking_genie.rb +++ b/lib/utils/networking_genie.rb @@ -1,13 +1,19 @@ # frozen_string_literal: true +require 'English' require 'socket' require_relative 'logg_man' +require_relative 'alert' +require_relative 'alert_queue_manager' # The class for setting up all the necessary system networking stuff for NETRAVE to work with without # interferring with the rest of the system class NetworkingGenie - def initialize(logger) + include Utilities + + def initialize(logger, alert_queue_manager) @loggman = logger + @alert_queue_manager = alert_queue_manager end def find_main_interface # rubocop:disable Metrics/MethodLength @@ -27,11 +33,40 @@ class NetworkingGenie nil end - def create_dummy_interface - # TODO: Implement method to create a dummy network interface + def create_dummy_interface(interface_name = 'dummy0') + # Check if the dummy module is loaded + use_sudo('modprobe dummy') + + # Check if the interface already exists + if `ip link show #{interface_name}`.empty? + # Create the dummy interface + use_sudo("ip link add #{interface_name} type dummy") + + # Set the interface up + use_sudo("ip link set #{interface_name} up") + else + @loggman.log_info("Interface #{interface_name} already exists.") + alert = Alert.new("Interface #{interface_name} already exists.", :info) + @alert_queue_manager.enqueue_alert(alert) + end end - def setup_traffic_mirroring - # TODO: Implement method to set up traffic mirroring from the main interface to the dummy interface + def setup_traffic_mirroring(main_interface, dummy_interface) # rubocop:disable Metrics/MethodLength + commands = [ + "tc qdisc del dev #{main_interface} ingress", + "tc qdisc add dev #{main_interface} handle ffff: ingress", + "tc filter add dev #{main_interface} parent ffff: u32 match + u32 0 0 action mirred egress mirror dev #{dummy_interface}" + ] + + begin + commands.each do |command| + use_sudo(command) + end + rescue StandardError => e + @loggman.log_error(e.message) + alert = Alert.new(e.message, :error) + @alert_queue_manager.enqueue_alert(alert) + end end end diff --git a/lib/utils/utilities.rb b/lib/utils/utilities.rb index 037fa95..c205b46 100644 --- a/lib/utils/utilities.rb +++ b/lib/utils/utilities.rb @@ -77,40 +77,59 @@ module Utilities def ask_for_sudo(logger) @loggman = logger - @loggman.log_info('Asking for sudo password...') + @loggman.log_info('Asking for sudo password... (This log entry will be removed)') Curses.addstr('Please enter your sudo password: ') - sudo_password = DCI.catch_input(true) - @loggman.log_info('Sudo password received.') - sudo_password - end + # use the dynamic curses input gem in secure mode to collect the sudo password + sudo_password = DCI.catch_input(false) + @loggman.log_info('Sudo password received. (This log entry will be removed)') - 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 + # Encrypt the sudo password right away and store it in an environment variable encrypted_sudo_password = encrypt_string_chacha20(sudo_password, @secret_key) ENV['SPW'] = encrypted_sudo_password + # Clear the unencrypted sudo password from memory + sudo_password.replace(' ' * sudo_password.length) + end + + def test_sudo + # Run a simple ls command with sudo privileges to test + use_sudo('ls') + true rescue Sudo::Wrapper::InvalidPassword false end - def clear_sudo_password + def deescalate_sudo # 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) + # Invalidate the user's cached credentials + Sudo::Wrapper.run('sudo -k', password: sudo_password) + # 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 + + def use_sudo(command) + # 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) + + # Use the sudo password to run the command + result = Sudo::Wrapper.run(command, password: sudo_password) + + # Clear the sudo password from memory + sudo_password.replace(' ' * sudo_password.length) + + result + end end