diff --git a/.gitignore b/.gitignore index 499c4e8..152086c 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,4 @@ build-iPhoneSimulator/ # Used by RuboCop. Remote config files pulled in from inherit_from directive. # .rubocop-https?--* bin/config.yml +lib/netrave.log diff --git a/bin/NETRAVE b/bin/NETRAVE index d8d26cd..babc018 100644 --- a/bin/NETRAVE +++ b/bin/NETRAVE @@ -10,7 +10,7 @@ require_relative '../lib/utils/utilities' include Utilities # rubocop:disable Style/MixinUsage # Create .env file if it doesn't exist -File.new('.env', 'w') unless File.exist?('.env') +File.open('.env', 'w') {} unless File.exist?('.env') # Load environment variables from .env file Dotenv.load @@ -42,7 +42,9 @@ if db_details.values.any?(&:nil?) end # Decrypt the password -db_details[:password] = decrypt_string_chacha20(db_details[:password], db_details[:key]) +if db_details[:password] && db_details[:key] + db_details[:password] = decrypt_string_chacha20(db_details[:password], db_details[:key]) +end # Test connection unless db_manager.test_db_connection(db_details) diff --git a/lib/utils/database_manager.rb b/lib/utils/database_manager.rb index 3c35f32..0f89bb0 100644 --- a/lib/utils/database_manager.rb +++ b/lib/utils/database_manager.rb @@ -13,18 +13,20 @@ class DatabaseManager @db = nil end - def test_db_connection(db_details) + def test_db_connection(db_details) # rubocop:disable Metrics/MethodLength # Decrypt the password before using it - decrypted_password = decrypt_string_chacha20(db_details[:password], db_details[:key]) - connection_string = "mysql2://#{db_details[:username]}:#{decrypted_password}@localhost/#{db_details[:database]}" - @db = Sequel.connect(connection_string) - # Try a simple query to test the connection - @db.run 'SELECT 1' - true + if db_details[:password] && db_details[:key] + decrypted_password = decrypt_string_chacha20(db_details[:password], db_details[:key]) + connection_string = "mysql2://#{db_details[:username]}:#{decrypted_password}@localhost/#{db_details[:database]}" + @db = Sequel.connect(connection_string) + # Try a simple query to test the connection + @db.run 'SELECT 1' + true + else + false + end rescue Sequel::DatabaseConnectionError false - ensure - @db&.disconnect end def create_system_info_table diff --git a/lib/utils/first_run_init.rb b/lib/utils/first_run_init.rb index 76258d7..71076fe 100644 --- a/lib/utils/first_run_init.rb +++ b/lib/utils/first_run_init.rb @@ -6,6 +6,7 @@ require 'dotenv' require_relative 'database_manager' require_relative 'system_information_gather' require_relative 'utilities' +require_relative 'logg_man' # first run class class FirstRunInit @@ -15,6 +16,7 @@ class FirstRunInit def initialize(db_manager = nil) @db_manager = db_manager || DatabaseManager.new @info_gatherer = SystemInformationGather.new(@db_manager) + @loggman = LoggMan.new end def run @@ -75,17 +77,23 @@ class FirstRunInit # Encrypt the password encrypted_password = encrypt_string_chacha20(password, key) - { username:, password: encrypted_password, key:, database: } + db_details = { username:, password: encrypted_password, key:, database: } + write_db_details_to_config_file(db_details) end def write_db_details_to_config_file(db_details) # Write the database details to the .env file File.open('.env', 'w') do |file| - file.puts "DB_USERNAME=#{db_details[:username]}" - file.puts "DB_PASSWORD=#{db_details[:password]}" - file.puts "DB_SECRET_KEY=#{db_details[:key]}" - file.puts "DB_DATABASE=#{db_details[:database]}" + file.puts %(DB_USERNAME="#{db_details[:username]}") + file.puts %(DB_PASSWORD="#{db_details[:password]}") + file.puts %(DB_SECRET_KEY="#{db_details[:key]}") + file.puts %(DB_DATABASE="#{db_details[:database]}") end + + # Load the .env file using dotenv + Dotenv.load + rescue StandardError => e + @loggman.log_error("Failed to write to .env file: #{e.message}") end def ask_for_default_mode diff --git a/lib/utils/logg_man.rb b/lib/utils/logg_man.rb new file mode 100644 index 0000000..af35426 --- /dev/null +++ b/lib/utils/logg_man.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require 'logger' + +# LoggMan class for handling logs +class LoggMan + def initialize + @logger = Logger.new('netrave.log') + end + + def log_info(message) + @logger.info(message) + end + + def log_error(message) + @logger.error(message) + end + + def log_warn(message) + @logger.warn(message) + end + + def log_debug(message) + @logger.debug(message) + end + + def log_fatal(message) + @logger.fatal(message) + end +end diff --git a/lib/utils/utilities.rb b/lib/utils/utilities.rb index 3f3fb6f..a31dfef 100644 --- a/lib/utils/utilities.rb +++ b/lib/utils/utilities.rb @@ -4,6 +4,7 @@ require 'securerandom' require 'digest' require 'base64' require 'openssl' +require_relative 'logg_man' # Utiltiies Module module Utilities @@ -32,31 +33,26 @@ module Utilities Base64.encode64(SecureRandom.bytes(32)).chomp end - def encrypt_string_chacha20(string, key) + def encrypt_string_chacha20(data, key) cipher = OpenSSL::Cipher.new('chacha20') cipher.encrypt - cipher.key = Base64.decode64(key) - encrypted = cipher.update(string) + cipher.final - Base64.encode64(encrypted).chomp + cipher.key = Base64.decode64(key) # Decode the key from Base64 + encrypted_data = cipher.update(data) + cipher.final + + loggman = LoggMan.new + loggman.log_debug("Data to be encrypted: #{data}") + loggman.log_debug("Key: #{key}") + loggman.log_debug("Encrypted data: #{encrypted_data}") + + Base64.encode64(encrypted_data).chomp end - def decrypt_string_chacha20(encrypted_string, key) - decipher = OpenSSL::Cipher.new('chacha20') - decipher.decrypt - decipher.key = Base64.decode64(key) - decrypted = Base64.decode64(encrypted_string) - decipher.update(decrypted) + decipher.final - end + def decrypt_string_chacha20(encrypted_data, key) + return nil if encrypted_data.nil? - # Encrypts a given data object using Blowfish and returns the encrypted string - def encrypt_data_blowfish(data, key) - plain_text = YAML.dump(data) - encrypt_string_blowfish(plain_text, key) - end - - # Decrypts a given encrypted string using Blowfish and returns the original data object - def decrypt_data_blowfish(encrypted_text, key) - plain_text = decrypt_string_blowfish(encrypted_text, key) - YAML.load(plain_text) + cipher = OpenSSL::Cipher.new('chacha20') + cipher.decrypt + cipher.key = Base64.decode64(key) # Decode the key from Base64 + cipher.update(Base64.decode64(encrypted_data)) + cipher.final end end