metasploit-framework/lib/msf/base/config.rb

356 lines
6.3 KiB
Ruby

# -*- coding: binary -*-
require 'fileutils'
module Msf
###
#
# This class wraps interaction with global configuration that can be used as a
# persistent storage point for configuration, logs, and other such fun things.
#
###
class Config < Hash
#
# The installation root directory for the distribution
#
InstallRoot = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..'))
#
# Determines the base configuration directory.
#
def self.get_config_root
# Use MSFCFGDIR environment variable first. See feature request #5797
val = Rex::Compat.getenv('MSF_CFGROOT_CONFIG')
if (val and File.directory?(val))
return val
end
# Windows-specific environment variables
['HOME', 'LOCALAPPDATA', 'APPDATA', 'USERPROFILE'].each do |dir|
val = Rex::Compat.getenv(dir)
if (val and File.directory?(val))
return File.join(val, ".msf#{Msf::Framework::Major}")
end
end
begin
# First we try $HOME/.msfx
File.expand_path("~#{FileSep}.msf#{Msf::Framework::Major}")
rescue ::ArgumentError
# Give up and install root + ".msfx"
InstallRoot + ".msf#{Msf::Framework::Major}"
end
end
#
# Default values
#
FileSep = File::SEPARATOR
Defaults =
{
'ConfigDirectory' => get_config_root,
'ConfigFile' => "config",
'ModuleDirectory' => "modules",
'ScriptDirectory' => "scripts",
'LogDirectory' => "logs",
'SessionLogDirectory' => "logs/sessions",
'PluginDirectory' => "plugins",
'DataDirectory' => "data",
'LootDirectory' => "loot",
'LocalDirectory' => "local"
}
##
#
# Class methods
#
##
#
# Returns the framework installation root.
#
def self.install_root
InstallRoot
end
#
# Calls the instance method.
#
def self.config_directory
self.new.config_directory
end
#
# Calls the instance method.
#
def self.module_directory
self.new.module_directory
end
#
# Calls the instance method.
#
def self.script_directory
self.new.script_directory
end
#
# Calls the instance method.
#
def self.log_directory
self.new.log_directory
end
#
# Calls the instance method.
#
def self.plugin_directory
self.new.plugin_directory
end
#
# Calls the instance method.
#
def self.user_plugin_directory
self.new.user_plugin_directory
end
#
# Calls the instance method.
#
def self.session_log_directory
self.new.session_log_directory
end
#
# Calls the instance method.
#
def self.loot_directory
self.new.loot_directory
end
#
# Calls the instance method.
#
def self.local_directory
self.new.local_directory
end
#
# Calls the instance method.
#
def self.user_module_directory
self.new.user_module_directory
end
#
# Calls the instance method.
#
def self.user_script_directory
self.new.user_script_directory
end
#
# Calls the instance method.
#
def self.data_directory
self.new.data_directory
end
#
# Calls the instance method.
#
def self.config_file
self.new.config_file
end
#
# Calls the instance method.
#
def self.history_file
self.new.history_file
end
#
# Calls the instance method.
#
def self.init
self.new.init
end
#
# Calls the instance method.
#
def self.load(path = nil)
self.new.load(path)
end
#
# Calls the instance method.
#
def self.save(opts)
self.new.save(opts)
end
#
# Updates the config class' self with the default hash.
#
def initialize
update(Defaults)
end
#
# Returns the installation root directory
#
def install_root
InstallRoot
end
#
# Returns the configuration directory default.
#
def config_directory
self['ConfigDirectory']
end
#
# Returns the full path to the configuration file.
#
def config_file
config_directory + FileSep + self['ConfigFile']
end
#
# Returns the full path to the configuration file.
#
def history_file
config_directory + FileSep + "history"
end
#
# Returns the global module directory.
#
def module_directory
install_root + FileSep + self['ModuleDirectory']
end
#
# Returns the path that scripts can be loaded from.
#
def script_directory
install_root + FileSep + self['ScriptDirectory']
end
#
# Returns the directory that log files should be stored in.
#
def log_directory
config_directory + FileSep + self['LogDirectory']
end
#
# Returns the directory that plugins are stored in.
#
def plugin_directory
install_root + FileSep + self['PluginDirectory']
end
#
# Returns the directory in which session log files are to reside.
#
def session_log_directory
config_directory + FileSep + self['SessionLogDirectory']
end
#
# Returns the directory in which captured data will reside.
#
def loot_directory
config_directory + FileSep + self['LootDirectory']
end
#
# Returns the directory in which locally-generated data will reside.
#
def local_directory
config_directory + FileSep + self['LocalDirectory']
end
#
# Returns the user-specific module base path
#
def user_module_directory
config_directory + FileSep + "modules"
end
#
# Returns the user-specific plugin base path
#
def user_plugin_directory
config_directory + FileSep + "plugins"
end
#
# Returns the user-specific script base path
#
def user_script_directory
config_directory + FileSep + "scripts"
end
#
# Returns the data directory
#
def data_directory
install_root + FileSep + self['DataDirectory']
end
#
# Initializes configuration, creating directories as necessary.
#
def init
FileUtils.mkdir_p(module_directory)
FileUtils.mkdir_p(config_directory)
FileUtils.mkdir_p(log_directory)
FileUtils.mkdir_p(session_log_directory)
FileUtils.mkdir_p(loot_directory)
FileUtils.mkdir_p(local_directory)
FileUtils.mkdir_p(user_module_directory)
FileUtils.mkdir_p(user_plugin_directory)
end
#
# Loads configuration from the supplied file path, or the default one if
# none is specified.
#
def load(path = nil)
path = config_file if (!path)
return Rex::Parser::Ini.new(path)
end
#
# Saves configuration to the path specified in the ConfigFile hash key or
# the default path is one isn't specified. The options should be group
# references that have named value pairs. Example:
#
# save(
# 'ExampleGroup' =>
# {
# 'Foo' => 'Cat'
# })
#
def save(opts)
ini = Rex::Parser::Ini.new(opts['ConfigFile'] || config_file)
ini.update(opts)
ini.to_file
end
end
end