#!/usr/local/bin/ruby18
#
# $Id: msfconsole 10743 2010-10-19 07:51:58Z hdm $
#
# This user interface provides users with a command console interface to the
# framework.
#
# $Revision: 10743 $
#

msfbase = __FILE__
while File.symlink?(msfbase)
	msfbase = File.expand_path(File.readlink(msfbase), File.dirname(msfbase))
end

$:.unshift(File.join(File.expand_path(File.dirname(msfbase)), 'lib'))
$:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB']

require 'optparse'

if(RUBY_PLATFORM =~ /mswin32/)
	$stderr.puts "[*] The msfconsole interface is not supported on the native Windows Ruby\n"
	$stderr.puts "    interpreter. Things will break, exploits will fail, payloads will not\n"
	$stderr.puts "    be handled correctly. Please install Cygwin or use Linux in VMWare.\n\n"
end

class OptsConsole
	#
	# Return a hash describing the options.
	#
	def self.parse(args)
		options = {}

		opts = OptionParser.new do |opts|
			opts.banner = "Usage: msfconsole [options]"

			opts.separator ""
			opts.separator "Specific options:"

			opts.on("-d", "-d", "Execute the console as defanged") do
				options['Defanged'] = true
			end

			opts.on("-r", "-r <filename>", "Execute the specified resource file") do |r|
				options['Resource'] ||= []
				options['Resource'] << r
			end

			opts.on("-c", "-c <filename>", "Load the specified configuration file") do |c|
				options['Config'] = c
			end

			opts.on("-m", "-m <directory>", "Specifies an additional module search path") do |m|
				options['ModulePath'] = m
			end

			opts.on("-y", "--yaml <database.yml>", "Specify a YAML file containing database settings") do |m|
				options['DatabaseYAML'] = m
			end

			opts.on("-e", "--environment <production|development>", "Specify the database environment to load from the YAML") do |m|
				options['DatabaseEnv'] = m
			end
						
			# Boolean switch.
			opts.on("-v", "--version", "Show version") do |v|
				options['Version'] = true
			end

			# Boolean switch.
			opts.on("-L", "--real-readline", "Use the system Readline library instead of RbReadline") do |v|
				options['RealReadline'] = true
			end

			# Boolean switch.
			opts.on("-n", "--no-database", "Disable database support") do |v|
				options['DisableDatabase'] = true
			end

			opts.separator ""
			opts.separator "Common options:"

			opts.on_tail("-h", "--help", "Show this message") do
				puts opts
				exit
			end
		end

		begin
			opts.parse!(args)
		rescue OptionParser::InvalidOption
			puts "Invalid option, try -h for usage"
			exit
		end

		options
	end
end

options = OptsConsole.parse(ARGV)

#
# NOTE: we don't require this until down here since we may not need it
# when processing certain options (currently only -h)
#
require 'rex'
require 'msf/ui'

#
# Everything below this line requires the framework.
#


#
# XXX: It would be nice to not have to load the entire framework just to get 
# the version number.
#
if (options['Version'])
	$stderr.puts 'Framework Version: ' + Msf::Framework::Version
	exit
end

begin
	Msf::Ui::Console::Driver.new(
		Msf::Ui::Console::Driver::DefaultPrompt,
		Msf::Ui::Console::Driver::DefaultPromptChar,
		options
	).run
rescue Interrupt
end
