Class: Msf::DataStore

Inherits:
Hash
  • Object
show all
Defined in:
lib/msf/core/data_store.rb

Overview

The data store is just a bitbucket that holds keyed values. It is used by various classes to hold option values and other state information.

Direct Known Subclasses

ModuleDataStore

Instance Method Summary collapse

Constructor Details

#initializeDataStore

Initializes the data store's internal state.


15
16
17
18
# File 'lib/msf/core/data_store.rb', line 15

def initialize()
  @imported    = Hash.new
  @imported_by = Hash.new
end

Instance Method Details

#[](k) ⇒ Object

Case-insensitive wrapper around hash lookup


35
36
37
# File 'lib/msf/core/data_store.rb', line 35

def [](k)
  super(find_key_case(k))
end

#[]=(k, v) ⇒ Object

Clears the imported flag for the supplied key since it's being set directly.


24
25
26
27
28
29
30
# File 'lib/msf/core/data_store.rb', line 24

def []=(k, v)
  k = find_key_case(k)
  @imported[k] = false
  @imported_by[k] = nil

  super(k,v)
end

#clearObject

Completely clear all values in the hash


211
212
213
214
# File 'lib/msf/core/data_store.rb', line 211

def clear
  self.keys.each {|k| self.delete(k) }
  self
end

#clear_non_user_definedObject

Remove all imported options from the data store.


197
198
199
200
201
202
203
204
205
206
# File 'lib/msf/core/data_store.rb', line 197

def clear_non_user_defined
  @imported.delete_if { |k, v|
    if (v and @imported_by[k] != 'self')
      self.delete(k)
      @imported_by.delete(k)
    end

    v
  }
end

#each(&block) ⇒ Object

Overrides the builtin 'each' operator to avoid the following exception on Ruby 1.9.2+

"can't add a new key into hash during iteration"

220
221
222
223
224
225
226
# File 'lib/msf/core/data_store.rb', line 220

def each(&block)
  list = []
  self.keys.sort.each do |sidx|
    list << [sidx, self[sidx]]
  end
  list.each(&block)
end

#from_file(path, name = 'global') ⇒ Object

Imports datastore values from the specified file path using the supplied name


172
173
174
175
176
177
178
179
180
181
182
# File 'lib/msf/core/data_store.rb', line 172

def from_file(path, name = 'global')
  begin
    ini = Rex::Parser::Ini.from_file(path)
  rescue
    return
  end

  if (ini.group?(name))
    import_options_from_hash(ini[name], false)
  end
end

#import_option(key, val, imported = true, imported_by = nil) ⇒ Object


124
125
126
127
128
129
# File 'lib/msf/core/data_store.rb', line 124

def import_option(key, val, imported=true, imported_by=nil)
  self.store(key, val)

  @imported[key]    = imported
  @imported_by[key] = imported_by
end

#import_options(options, imported_by = nil, overwrite = false) ⇒ Object

This method is a helper method that imports the default value for all of the supplied options


60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/msf/core/data_store.rb', line 60

def import_options(options, imported_by = nil, overwrite = false)
  options.each_option { |name, opt|
    # If there's already a value defined for this option, then skip it
    # and don't import it.
    next if self.has_key?(name) and overwrite == false

    # If the option has a default value, import it, but only if the
    # datastore doesn't already have a value set for it.
    if ((opt.default != nil) and (overwrite or self[name] == nil))
      import_option(name, opt.default.to_s, true, imported_by)
    end
  }
end

#import_options_from_hash(option_hash, imported = true, imported_by = nil) ⇒ Object

Imports options from a hash and stores them in the datastore.


118
119
120
121
122
# File 'lib/msf/core/data_store.rb', line 118

def import_options_from_hash(option_hash, imported = true, imported_by = nil)
  option_hash.each_pair { |key, val|
    import_option(key, val.to_s, imported, imported_by)
  }
end

#import_options_from_s(option_str, delim = nil) ⇒ Object

Imports option values from a whitespace separated string in VAR=VAL format.


78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/msf/core/data_store.rb', line 78

def import_options_from_s(option_str, delim = nil)
  hash = {}

  # Figure out the deliminter, default to space.
  if (delim.nil?)
    delim = /\s/

    if (option_str.split('=').length <= 2 or option_str.index(',') != nil)
      delim = ','
    end
  end

  # Split on the deliminter
  option_str.split(delim).each { |opt|
    var, val = opt.split('=')

    next if (var =~ /^\s+$/)


    # Invalid parse?  Raise an exception and let those bastards know.
    if (var == nil or val == nil)
      var = "unknown" if (!var)

      raise Rex::ArgumentParseError, "Invalid option specified: #{var}",
        caller
    end

    # Remove trailing whitespaces from the value
    val.gsub!(/\s+$/, '')

    # Store the value
    hash[var] = val
  }

  import_options_from_hash(hash)
end

#store(k, v) ⇒ Object

Case-insensitive wrapper around store


42
43
44
# File 'lib/msf/core/data_store.rb', line 42

def store(k,v)
  super(find_key_case(k), v)
end

#to_file(path, name = 'global') ⇒ Object

Persists the contents of the data store to a file


155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/msf/core/data_store.rb', line 155

def to_file(path, name = 'global')
  ini = Rex::Parser::Ini.new(path)

  ini.add_group(name)

  # Save all user-defined options to the file.
  user_defined.each_pair { |k, v|
    ini[name][k] = v
  }

  ini.to_file(path)
end

#to_hObject


144
145
146
147
148
149
150
# File 'lib/msf/core/data_store.rb', line 144

def to_h
  datastore_hash = {}
  self.keys.each do |k|
    datastore_hash[k.to_s] = self[k].to_s
  end
  datastore_hash
end

#to_s(delim = ' ') ⇒ Object

Serializes the options in the datastore to a string.


134
135
136
137
138
139
140
141
142
# File 'lib/msf/core/data_store.rb', line 134

def to_s(delim = ' ')
  str = ''

  keys.sort.each { |key|
    str << "#{key}=#{self[key]}" + ((str.length) ? delim : '')
  }

  return str
end

#update_value(k, v) ⇒ Object

Updates a value in the datastore with the specified name, k, to the specified value, v. This update does not alter the imported status of the value.


52
53
54
# File 'lib/msf/core/data_store.rb', line 52

def update_value(k, v)
  self.store(k, v)
end

#user_definedObject

Returns a hash of user-defined datastore values. The returned hash does not include default option values.


188
189
190
191
192
# File 'lib/msf/core/data_store.rb', line 188

def user_defined
  reject { |k, v|
    @imported[k] == true
  }
end