Class: Aspisec::Config — Documentation by YARD 0.9.36

# Class: Aspisec::Config

Inherits:
  Object
  - Object
  - Aspisec::Config
  show all

Defined in:
  lib-ruby/aspisec/config.rb,
  lib-ruby/aspisec/configs/ffuf.rb,
  lib-ruby/aspisec/configs/john.rb,
  lib-ruby/aspisec/configs/amass.rb,
  lib-ruby/aspisec/configs/mobsf.rb,
  lib-ruby/aspisec/configs/recaf.rb,
  lib-ruby/aspisec/configs/dbgate.rb,
  lib-ruby/aspisec/configs/lsassy.rb,
  lib-ruby/aspisec/configs/ncrack.rb,
  lib-ruby/aspisec/configs/sqlmap.rb,
  lib-ruby/aspisec/configs/hashcat.rb,
  lib-ruby/aspisec/configs/netexec.rb,
  lib-ruby/aspisec/configs/remmina.rb,
  lib-ruby/aspisec/configs/semgrep.rb,
  lib-ruby/aspisec/configs/weevely.rb,
  lib-ruby/aspisec/configs/whatwaf.rb,
  lib-ruby/aspisec/configs/jwt_tool.rb,
  lib-ruby/aspisec/configs/filezilla.rb,
  lib-ruby/aspisec/configs/manspider.rb,
  lib-ruby/aspisec/configs/bloodhound.rb,
  lib-ruby/aspisec/configs/metasploit.rb,
  lib-ruby/aspisec/configs/spiderfoot.rb,
  lib-ruby/aspisec/configs/crackmapexec.rb,
  lib-ruby/aspisec/configs/theharvester.rb,
  lib-ruby/aspisec/configs/mongodb_compass.rb,
  lib-ruby/aspisec/configs/mongodb_mongosh.rb,
  lib-ruby/aspisec/configs/home_history_files.rb

## Overview

Managing the configuration file (location, creation, parsing)

## Defined Under Namespace

Modules: Configs

## Constant Summary collapse

CONFIG_FILENAME =

      'aspisec.config.yaml'

DEFAULT_CONFIG =

      {
        'aspisec' => {
          'version' => Aspisec::VERSION,
          # Auto clean, remove files without asking confirmation
          'autoclean' => {
            'enabled' => false
          },
          # Display the description of each location to explain what the file /
          # directory is storing
          'describe' => {
            'enabled' => true
          }
        },
        'tools' => {
          # Example of a tool configuration
          'example' => {
            # Putting this value to false allow to disable the check for this module only
            'enabled' => false,
            'location' => {
              # The base location where the tool stores the confidential stuff to clean
              # $XDG_DATA_HOME is evaluated with a XDG library so even if the environment
              # variable doesn't exist it will be replaced with the default standard value
              'base' => '$XDG_DATA_HOME/tools/ex',
              'logs' => {
                # Path to the confidential file n°1
                # <base> will be replaced by location.base value
                'path' => '<base>/output',
                # Each file check can be individually turned off rather than disabling the whole module
                'enaled' => false,
                # The description explain which client-related data is stored there and how it is sensitive.
                # It generally says if it's a file or directory.
                'description' => 'The directory containing log files. Logs contain IP addresses and hostnames.'
              }
            }
          },
          'sqlmap' => Configs::SQLMAP,
          'crackmapexec' => Configs::CRACKMAPEXEC,
          'netexec' => Configs::NETEXEC,
          'hashcat' => Configs::HASHCAT,
          'theharvester' => Configs::THEHARVESTER,
          'john' => Configs::JOHN,
          'metasploit' => Configs::METASPLOIT,
          'jwt_tool' => Configs::JWT_TOOL,
          'manspider' => Configs::MANSPIDER,
          'ncrack' => Configs::NCRACK,
          'weevely' => Configs::WEEVELY,
          'spiderfoot' => Configs::SPIDERFOOT,
          'remmina' => Configs::REMMINA,
          'mobsf' => Configs::MOBSF,
          'mongodb-compass' => Configs::MONGODB_COMPASS,
          'mongodb-mongosh' => Configs::MONGODB_MONGOSH,
          'lsassy' => Configs::LSASSY,
          'semgrep' => Configs::SEMGREP,
          'whatwaf' => Configs::WHATWAF,
          'amass' => Configs::AMASS,
          'bloodhound' => Configs::BLOODHOUND,
          'ffuf' => Configs::FFUF,
          'recaf' => Configs::RECAF,
          'dbgate' => Configs::DBGATE,
          'home-history-files' => Configs::HOME_HISTORY_FILES,
          'filezilla' => Configs::FILEZILLA
        },
        'audit' => {
          'enabled' => false,
          'location' => {
            'base' => '$HOME/Projets'
          }
        }
      }.freeze

## Instance Attribute Summary collapse

- #conf ⇒ Hash readonly

  The parsed Aspisec configuration.

## Class Method Summary collapse

- .expand_path_variables(path) ⇒ String

  Evaluate XDG variables and $HOME in file path.

## Instance Method Summary collapse

- #check_version ⇒ true|false

  Comparison between Aspisec tool version and Aspisec configuration version.

- #config_exist? ⇒ true|false

  Check if the Aspisec configuration file exists or not.

- #config_filepath ⇒ String

  Get the Aspisec configuration file path.

- #create_config ⇒ Object

  Create the configuration file with default value at default location if it doesn't already exist.

- #expand_path_conf! ⇒ Object

  Expand all base location with Config.expand_path_variables in the configuration + expand the custom `<base>` tags.

- #expand_path_variables(path) ⇒ Object
- #initialize(logger = nil) ⇒ Config constructor

  Load config.

- #load_config ⇒ Hash|nil

  Read and parse (YAML ➡️ Ruby Hash) the config.

## Constructor Details

### #initialize(logger = nil) ⇒ `Config`

Load config. or create a default config. file if not existing.
Also parse and interprete custom values.

Examples:

    # With default logger
    cnf = Aspisec::Config.new
    cnf.conf
    # With custom logger
    logger = Aspisec::Logger.new(0).logger
    cnf = Aspisec::Config.new(logger)
    cnf.conf

Parameters:

- logger (`TTY::Logger`) (defaults to: `nil`) —

  logger instance. See Logger.
  If none is provided, a default logger with log level 2 is created.
  See Logger::LOG_LEVEL.

    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    # File 'lib-ruby/aspisec/config.rb', line 103

    def initialize(logger = nil)
      # Set log level
      @logger = logger || Aspisec::Logger.new.logger
      # Create the configuration file if it doesn't exist
      create_config unless config_exist?
      # Else load it
      @conf = load_config
      # Check the version of the configuration
      check_version
      # Replace the path variables / plaholders with real values
      expand_path_conf!
    end

## Instance Attribute Details

### #conf ⇒ `Hash` (readonly)

The parsed Aspisec configuration

Returns:

- (`Hash`) —

  the Aspisec configuration object

    88
    89
    90
    # File 'lib-ruby/aspisec/config.rb', line 88

    def conf
      @conf
    end

## Class Method Details

### .expand_path_variables(path) ⇒ `String`

Note:

Arguments other than Strings are returned untouched, useful to iterate over configuration values

Evaluate XDG variables and $HOME in file path

Examples:

    conf.expand_path_variables('$XDG_DATA_HOME/sqlmap')
    # => "/home/noraj/.local/share/sqlmap"

Parameters:

- path (`String`) —

  path with variables

Returns:

- (`String`) —

  the absolute version of the evaluated path

    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    # File 'lib-ruby/aspisec/config.rb', line 194

    def self.expand_path_variables(path)
      return path unless path.is_a?(String) # not a path, let untouched

      case path
      when /\$XDG_CONFIG_HOME/
        path.sub!('$XDG_CONFIG_HOME', SXDG::XDG_CONFIG_HOME)
      when /\$XDG_DATA_HOME/
        path.sub!('$XDG_DATA_HOME', SXDG::XDG_DATA_HOME)
      when /\$HOME/
        path.sub!('$HOME', Dir.home)
      end
      File.expand_path(path)
    end

## Instance Method Details

### #check_version ⇒ `true|false`

Comparison between Aspisec tool version and Aspisec configuration version

Returns:

- (`true|false`) —

  true when the tool and configuration version match

    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    # File 'lib-ruby/aspisec/config.rb', line 118

    def check_version
      version = @conf.dig('aspisec', 'version')
      matching = true
      if version.nil?
        @logger.warn('No version found in the configuration (old version).')
        matching = false
      elsif Gem::Version.new(Aspisec::VERSION) > Gem::Version.new(version)
        message = "The configuration is older (#{version}) than the tool (#{Aspisec::VERSION})." \
                  'Some module or features may be missing.'
        @logger.warn(message)
        matching = false
      elsif Gem::Version.new(Aspisec::VERSION) < Gem::Version.new(version)
        message = "The configuration is newer (#{version}) than the tool (#{Aspisec::VERSION})." \
                  'You may experience issues.'
        @logger.warn(message)
        matching = false
      end
      unless matching
        @logger.warn("\"rm #{config_filepath}\" if you want Aspisec to recreate a default configuration file")
      end
      matching
    end

### #config_exist? ⇒ `true|false`

Check if the Aspisec configuration file exists or not

Returns:

- (`true|false`)

    173
    174
    175
    176
    177
    178
    179
    180
    # File 'lib-ruby/aspisec/config.rb', line 173

    def config_exist?
      # Logging this floods debug info and is not meaningful
      # exist = File.exist?(config_filepath)
      # neg = exist ? '' : 'does not'
      # @logger.debug("The configuration file #{config_filepath} #{neg} exist")
      # exist
      File.exist?(config_filepath)
    end

### #config_filepath ⇒ `String`

Get the Aspisec configuration file path

Returns:

- (`String`) —

  absolute file path

    167
    168
    169
    # File 'lib-ruby/aspisec/config.rb', line 167

    def config_filepath
      File.join(SXDG::XDG_CONFIG_HOME, 'aspisec', CONFIG_FILENAME) # /home/noraj/.config/aspisec/aspisec.config.yaml
    end

### #create_config ⇒ `Object`

Create the configuration file with default value at default location if it doesn't already exist

    155
    156
    157
    158
    159
    160
    161
    162
    163
    # File 'lib-ruby/aspisec/config.rb', line 155

    def create_config
      return if config_exist?

      parent_dir = File.dirname(config_filepath)
      # create parent folder recursively if it doesn't already exist
      FileUtils.mkpath(parent_dir)
      @logger.info("Creating configuration file: #{config_filepath}")
      File.write(config_filepath, YAML.dump(DEFAULT_CONFIG))
    end

### #expand_path_conf! ⇒ `Object`

Expand all base location with expand_path_variables in the configuration

- expand the custom `<base>` tags

    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    # File 'lib-ruby/aspisec/config.rb', line 210

    def expand_path_conf!
      @conf['tools'].each_key do |tool|
        base_path = @conf.dig('tools', tool, 'location', 'base')
        @conf['tools'][tool]['location']['base'] = expand_path_variables(base_path)
        @conf['tools'][tool]['location'].each_key do |k|
          unless k == 'base'
            feature_path = @conf.dig('tools', tool, 'location', k, 'path')
            @conf['tools'][tool]['location'][k]['path'] = feature_path.sub('<base>', base_path) if feature_path
          end
        end
      end
      @conf['audit']['location']['base'] = expand_path_variables(@conf.dig('audit', 'location', 'base'))
      @conf
    end

### #expand_path_variables(path) ⇒ `Object`

Note:

see expand_path_variables

    183
    184
    185
    # File 'lib-ruby/aspisec/config.rb', line 183

    def expand_path_variables(path)
      Config.expand_path_variables(path)
    end

### #load_config ⇒ `Hash|nil`

Read and parse (YAML ➡️ Ruby Hash) the config. file

Returns:

- (`Hash|nil`) —

  the corresponding Ruby object parsed from the YAML file
  or `nil` if the configuration file doesn't exist

    144
    145
    146
    147
    148
    149
    150
    151
    152
    # File 'lib-ruby/aspisec/config.rb', line 144

    def load_config
      if config_exist?
        @logger.debug("Loading configuration from #{config_filepath}")
        YAML.load_file(config_filepath, symbolize_names: false)
      else
        @logger.warn('Configuration not loaded')
        nil
      end
    end