Run migrations when connection already established in console

MSP-10955

`Msf::Ui::Console::Driver#initialize` doesn't call
`framework.db.connect` if it can't find the the `database.yml`, but when
using `msfpro`, the connection is already established, so the console
doesn't need to know where the database file is and should just run the
migrations so that `framework.db.migrate` can be set and
`framework.db.active` will return `true`.
bug/bundler_fix
Luke Imhoff 2014-08-06 19:55:51 -05:00
parent 5af4959558
commit 1d430dbb45
No known key found for this signature in database
GPG Key ID: 5B1FB01FB33356F8
2 changed files with 73 additions and 47 deletions

View File

@ -228,21 +228,14 @@ class DBManager
# Configure the database adapter
ActiveRecord::Base.establish_connection(nopts)
end
# Migrate the database, if needed
migrate
# Set the default workspace
framework.db.workspace = framework.db.default_workspace
# Flag that migration has completed
self.migrated = true
rescue ::Exception => e
self.error = e
elog("DB.connect threw an exception: #{e}")
dlog("Call stack: #{$@.join"\n"}", LEV_1)
return false
ensure
after_establish_connection
# Database drivers can reset our KCODE, do not let them
$KCODE = 'NONE' if RUBY_VERSION =~ /^1\.8\./
end
@ -250,6 +243,29 @@ class DBManager
true
end
# Finishes {#connect} after `ActiveRecord::Base.establish_connection` has succeeded by {#migrate migrating database}
# and setting {#workspace}.
#
# @return [void]
def after_establish_connection
self.migrated = false
begin
# Migrate the database, if needed
migrate
# Set the default workspace
framework.db.workspace = framework.db.default_workspace
rescue ::Exception => exception
self.error = exception
elog("DB.connect threw an exception: #{exception}")
dlog("Call stack: #{exception.backtrace.join("\n")}", LEV_1)
else
# Flag that migration has completed
self.migrated = true
end
end
#
# Attempt to create the database
#

View File

@ -176,50 +176,60 @@ class Driver < Msf::Ui::Driver
end
end
# Look for our database configuration in the following places, in order:
# command line arguments
# environment variable
# configuration directory (usually ~/.msf3)
dbfile = opts['DatabaseYAML']
dbfile ||= ENV["MSF_DATABASE_CONFIG"]
dbfile ||= File.join(Msf::Config.get_config_root, "database.yml")
if (dbfile and File.exists? dbfile)
if File.readable?(dbfile)
dbinfo = YAML.load(File.read(dbfile))
dbenv = opts['DatabaseEnv'] || Rails.env
db = dbinfo[dbenv]
else
print_error("Warning, #{dbfile} is not readable. Try running as root or chmod.")
end
if not db
print_error("No database definition for environment #{dbenv}")
else
if not framework.db.connect(db)
if framework.db.error.to_s =~ /RubyGem version.*pg.*0\.11/i
print_error("***")
print_error("*")
print_error("* Metasploit now requires version 0.11 or higher of the 'pg' gem for database support")
print_error("* There a three ways to accomplish this upgrade:")
print_error("* 1. If you run Metasploit with your system ruby, simply upgrade the gem:")
print_error("* $ rvmsudo gem install pg ")
print_error("* 2. Use the Community Edition web interface to apply a Software Update")
print_error("* 3. Uninstall, download the latest version, and reinstall Metasploit")
print_error("*")
print_error("***")
print_error("")
print_error("")
end
if framework.db.connection_established?
framework.db.after_establish_connection
else
# Look for our database configuration in the following places, in order:
# command line arguments
# environment variable
# configuration directory (usually ~/.msf3)
dbfile = opts['DatabaseYAML']
dbfile ||= ENV["MSF_DATABASE_CONFIG"]
dbfile ||= File.join(Msf::Config.get_config_root, "database.yml")
print_error("Failed to connect to the database: #{framework.db.error}")
if (dbfile and File.exists? dbfile)
if File.readable?(dbfile)
dbinfo = YAML.load(File.read(dbfile))
dbenv = opts['DatabaseEnv'] || Rails.env
db = dbinfo[dbenv]
else
self.framework.modules.refresh_cache_from_database
print_error("Warning, #{dbfile} is not readable. Try running as root or chmod.")
end
if self.framework.modules.cache_empty?
print_status("The initial module cache will be built in the background, this can take 2-5 minutes...")
end
if not db
print_error("No database definition for environment #{dbenv}")
else
framework.db.connect(db)
end
end
end
# framework.db.active will be true if after_establish_connection ran directly when connection_established? was
# already true or if framework.db.connect called after_establish_connection.
if framework.db.active
self.framework.modules.refresh_cache_from_database
if self.framework.modules.cache_empty?
print_status("The initial module cache will be built in the background, this can take 2-5 minutes...")
end
elsif !framework.db.error.nil?
if framework.db.error.to_s =~ /RubyGem version.*pg.*0\.11/i
print_error("***")
print_error("*")
print_error("* Metasploit now requires version 0.11 or higher of the 'pg' gem for database support")
print_error("* There a three ways to accomplish this upgrade:")
print_error("* 1. If you run Metasploit with your system ruby, simply upgrade the gem:")
print_error("* $ rvmsudo gem install pg ")
print_error("* 2. Use the Community Edition web interface to apply a Software Update")
print_error("* 3. Uninstall, download the latest version, and reinstall Metasploit")
print_error("*")
print_error("***")
print_error("")
print_error("")
end
print_error("Failed to connect to the database: #{framework.db.error}")
end
end
# Initialize the module paths only if we didn't get passed a Framework instance