2006-03-21 04:37:48 +00:00
|
|
|
require 'msf/core'
|
|
|
|
require 'msf/core/db'
|
2009-12-28 00:21:21 +00:00
|
|
|
require 'msf/core/task_manager'
|
2006-03-21 04:37:48 +00:00
|
|
|
|
|
|
|
module Msf
|
|
|
|
|
|
|
|
###
|
|
|
|
#
|
2009-10-25 17:18:23 +00:00
|
|
|
# The db module provides persistent storage and events. This class should be instantiated LAST
|
|
|
|
# as the active_suppport library overrides Kernel.require, slowing down all future code loads.
|
2006-03-21 04:37:48 +00:00
|
|
|
#
|
|
|
|
###
|
|
|
|
|
|
|
|
class DBManager
|
|
|
|
|
|
|
|
# Provides :framework and other accessors
|
|
|
|
include Framework::Offspring
|
2009-11-14 21:41:38 +00:00
|
|
|
|
2006-03-21 04:37:48 +00:00
|
|
|
# Returns true if we are ready to load/store data
|
|
|
|
attr_accessor :active
|
2009-11-14 21:41:38 +00:00
|
|
|
|
2006-03-21 04:37:48 +00:00
|
|
|
# Returns true if the prerequisites have been installed
|
|
|
|
attr_accessor :usable
|
2009-11-14 21:41:38 +00:00
|
|
|
|
2009-03-28 20:45:46 +00:00
|
|
|
# Returns the list of usable database drivers
|
|
|
|
attr_accessor :drivers
|
2009-11-14 21:41:38 +00:00
|
|
|
|
2009-03-28 21:42:30 +00:00
|
|
|
# Returns the active driver
|
|
|
|
attr_accessor :driver
|
2009-11-14 21:41:38 +00:00
|
|
|
|
2009-06-03 16:28:28 +00:00
|
|
|
# Stores the error message for why the db was not loaded
|
|
|
|
attr_accessor :error
|
2009-11-14 21:41:38 +00:00
|
|
|
|
2009-12-28 00:21:21 +00:00
|
|
|
# Stores a TaskManager for serializing database events
|
|
|
|
attr_accessor :sink
|
|
|
|
|
2006-03-21 04:37:48 +00:00
|
|
|
def initialize(framework)
|
2009-11-14 21:41:38 +00:00
|
|
|
|
2006-03-21 04:37:48 +00:00
|
|
|
self.framework = framework
|
|
|
|
@usable = false
|
|
|
|
@active = false
|
2009-11-14 21:41:38 +00:00
|
|
|
|
2008-11-09 21:54:04 +00:00
|
|
|
#
|
2009-07-14 18:27:34 +00:00
|
|
|
# Prefer our local copy of active_record and active_support
|
2008-11-09 21:54:04 +00:00
|
|
|
#
|
|
|
|
dir_ar = File.join(Msf::Config.data_directory, 'msfweb', 'vendor', 'rails', 'activerecord', 'lib')
|
|
|
|
if(File.directory?(dir_ar) and not $:.include?(dir_ar))
|
|
|
|
$:.unshift(dir_ar)
|
|
|
|
end
|
2009-11-14 21:41:38 +00:00
|
|
|
|
2009-07-14 18:27:34 +00:00
|
|
|
dir_as = File.join(Msf::Config.data_directory, 'msfweb', 'vendor', 'rails', 'activesupport', 'lib')
|
|
|
|
if(File.directory?(dir_as) and not $:.include?(dir_as))
|
|
|
|
$:.unshift(dir_as)
|
|
|
|
end
|
2009-11-14 21:41:38 +00:00
|
|
|
|
2007-02-11 23:47:34 +00:00
|
|
|
# Load ActiveRecord if it is available
|
2009-11-14 21:41:38 +00:00
|
|
|
begin
|
2007-02-11 23:47:34 +00:00
|
|
|
require 'rubygems'
|
|
|
|
require 'active_record'
|
2009-07-14 18:27:34 +00:00
|
|
|
require 'active_support'
|
2006-03-21 04:37:48 +00:00
|
|
|
require 'msf/core/db_objects'
|
2009-12-14 22:52:34 +00:00
|
|
|
require 'msf/core/model'
|
2010-03-20 21:40:59 +00:00
|
|
|
|
|
|
|
# Database drivers can reset our KCODE, do not let them
|
2010-03-22 12:34:06 +00:00
|
|
|
$KCODE = 'NONE' if RUBY_VERSION =~ /^1\.8\./
|
2010-03-20 21:40:59 +00:00
|
|
|
|
2007-02-11 23:47:34 +00:00
|
|
|
@usable = true
|
2009-11-14 21:41:38 +00:00
|
|
|
|
2006-03-21 04:37:48 +00:00
|
|
|
rescue ::Exception => e
|
2009-06-03 16:28:28 +00:00
|
|
|
self.error = e
|
2008-12-19 07:11:08 +00:00
|
|
|
elog("DB is not enabled due to load error: #{e}")
|
2009-06-03 16:28:28 +00:00
|
|
|
return
|
2006-03-21 04:37:48 +00:00
|
|
|
end
|
2009-11-14 21:41:38 +00:00
|
|
|
|
2009-03-28 20:45:46 +00:00
|
|
|
#
|
|
|
|
# Determine what drivers are available
|
|
|
|
#
|
|
|
|
initialize_drivers
|
2009-12-28 00:21:21 +00:00
|
|
|
|
|
|
|
#
|
|
|
|
# Instantiate the database sink
|
|
|
|
#
|
|
|
|
initialize_sink
|
2009-03-28 20:45:46 +00:00
|
|
|
end
|
2009-11-14 21:41:38 +00:00
|
|
|
|
|
|
|
#
|
2009-12-28 00:21:21 +00:00
|
|
|
# Scan through available drivers
|
2009-03-28 20:45:46 +00:00
|
|
|
#
|
|
|
|
def initialize_drivers
|
|
|
|
self.drivers = []
|
2009-03-28 21:42:30 +00:00
|
|
|
tdrivers = %W{ sqlite3 mysql postgresql }
|
2009-03-28 20:45:46 +00:00
|
|
|
tdrivers.each do |driver|
|
|
|
|
begin
|
2010-03-29 17:04:40 +00:00
|
|
|
ActiveRecord::Base.default_timezone = :utc
|
2009-03-28 20:45:46 +00:00
|
|
|
ActiveRecord::Base.establish_connection(:adapter => driver)
|
2009-11-14 21:41:38 +00:00
|
|
|
if(self.respond_to?("driver_check_#{driver}"))
|
|
|
|
self.send("driver_check_#{driver}")
|
|
|
|
end
|
2009-03-28 20:45:46 +00:00
|
|
|
ActiveRecord::Base.remove_connection
|
|
|
|
self.drivers << driver
|
|
|
|
rescue ::Exception
|
|
|
|
end
|
|
|
|
end
|
2009-11-14 21:41:38 +00:00
|
|
|
|
2009-03-28 21:42:30 +00:00
|
|
|
if(not self.drivers.empty?)
|
|
|
|
self.driver = self.drivers[0]
|
|
|
|
end
|
2010-03-20 21:40:59 +00:00
|
|
|
|
|
|
|
# Database drivers can reset our KCODE, do not let them
|
2010-03-22 12:34:06 +00:00
|
|
|
$KCODE = 'NONE' if RUBY_VERSION =~ /^1\.8\./
|
2006-03-21 04:37:48 +00:00
|
|
|
end
|
2009-11-14 21:41:38 +00:00
|
|
|
|
2009-12-28 00:21:21 +00:00
|
|
|
#
|
|
|
|
# Create a new database sink and initialize it
|
|
|
|
#
|
|
|
|
def initialize_sink
|
|
|
|
self.sink = TaskManager.new(framework)
|
|
|
|
self.sink.start
|
|
|
|
end
|
|
|
|
|
|
|
|
#
|
|
|
|
# Add a new task to the sink
|
|
|
|
#
|
|
|
|
def queue(proc)
|
|
|
|
self.sink.queue_proc(proc)
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2009-11-14 21:41:38 +00:00
|
|
|
# Verify that sqlite3 is ready
|
|
|
|
def driver_check_sqlite3
|
|
|
|
require 'sqlite3'
|
|
|
|
end
|
|
|
|
|
|
|
|
# Verify that mysql is ready
|
|
|
|
def driver_check_mysql
|
|
|
|
require 'mysql'
|
|
|
|
end
|
|
|
|
|
2006-03-21 04:37:48 +00:00
|
|
|
#
|
|
|
|
# Connects this instance to a database
|
|
|
|
#
|
|
|
|
def connect(opts={})
|
2007-12-31 04:05:51 +00:00
|
|
|
|
2006-03-21 04:37:48 +00:00
|
|
|
return false if not @usable
|
2009-11-14 21:41:38 +00:00
|
|
|
|
2007-07-17 18:42:26 +00:00
|
|
|
nopts = opts.dup
|
|
|
|
if (nopts['port'])
|
|
|
|
nopts['port'] = nopts['port'].to_i
|
|
|
|
end
|
2009-11-14 21:41:38 +00:00
|
|
|
|
2010-03-14 03:54:54 +00:00
|
|
|
nopts['pool'] = 256
|
2010-03-04 07:10:20 +00:00
|
|
|
|
2006-03-21 04:37:48 +00:00
|
|
|
begin
|
2009-11-14 21:41:38 +00:00
|
|
|
# Configure the database adapter
|
2007-07-17 19:01:04 +00:00
|
|
|
ActiveRecord::Base.establish_connection(nopts)
|
2009-12-14 22:52:34 +00:00
|
|
|
|
|
|
|
# Migrate the database, if needed
|
|
|
|
migrate
|
|
|
|
|
|
|
|
# Set the default workspace
|
|
|
|
framework.db.workspace = framework.db.default_workspace
|
2006-03-21 04:37:48 +00:00
|
|
|
rescue ::Exception => e
|
2009-11-14 21:41:38 +00:00
|
|
|
self.error = e
|
2008-12-19 07:11:08 +00:00
|
|
|
elog("DB.connect threw an exception: #{e}")
|
2009-12-29 23:48:45 +00:00
|
|
|
dlog("Call stack: #{$@.join"\n"}", LEV_1)
|
2006-03-21 04:37:48 +00:00
|
|
|
return false
|
2010-03-20 21:40:59 +00:00
|
|
|
ensure
|
|
|
|
# Database drivers can reset our KCODE, do not let them
|
2010-03-22 12:34:06 +00:00
|
|
|
$KCODE = 'NONE' if RUBY_VERSION =~ /^1\.8\./
|
2006-03-21 04:37:48 +00:00
|
|
|
end
|
2009-11-14 21:41:38 +00:00
|
|
|
|
2006-03-21 04:37:48 +00:00
|
|
|
@active = true
|
|
|
|
end
|
2009-11-14 21:41:38 +00:00
|
|
|
|
2006-03-21 04:37:48 +00:00
|
|
|
#
|
|
|
|
# Disconnects a database session
|
|
|
|
#
|
|
|
|
def disconnect
|
|
|
|
begin
|
|
|
|
ActiveRecord::Base.remove_connection
|
|
|
|
rescue ::Exception => e
|
2009-11-14 21:41:38 +00:00
|
|
|
self.error = e
|
2008-12-19 07:11:08 +00:00
|
|
|
elog("DB.disconnect threw an exception: #{e}")
|
2010-03-20 21:40:59 +00:00
|
|
|
ensure
|
|
|
|
# Database drivers can reset our KCODE, do not let them
|
2010-03-22 12:34:06 +00:00
|
|
|
$KCODE = 'NONE' if RUBY_VERSION =~ /^1\.8\./
|
2006-03-21 04:37:48 +00:00
|
|
|
end
|
|
|
|
@active = false
|
|
|
|
end
|
|
|
|
|
2009-12-07 17:03:27 +00:00
|
|
|
#
|
|
|
|
# Migrate database to latest schema version
|
|
|
|
#
|
|
|
|
def migrate(verbose = false)
|
|
|
|
begin
|
|
|
|
migrate_dir = ::File.join(Msf::Config.install_root, "data", "sql", "migrate")
|
|
|
|
ActiveRecord::Migration.verbose = verbose
|
|
|
|
ActiveRecord::Migrator.migrate(migrate_dir, nil)
|
|
|
|
rescue ::Exception => e
|
|
|
|
self.error = e
|
|
|
|
elog("DB.migrate threw an exception: #{e}")
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
2009-12-23 20:37:30 +00:00
|
|
|
def workspace=(workspace)
|
|
|
|
@workspace_name = workspace.name
|
|
|
|
end
|
|
|
|
|
|
|
|
def workspace
|
|
|
|
framework.db.find_workspace(@workspace_name)
|
|
|
|
end
|
|
|
|
|
2006-03-21 04:37:48 +00:00
|
|
|
end
|
2008-11-09 21:54:04 +00:00
|
|
|
end
|
2009-11-14 21:41:38 +00:00
|
|
|
|