#!/usr/local/bin/ruby18
#
# $Id: msfd 9212 2010-05-03 17:13:09Z jduck $
#
# This user interface listens on a port and provides clients that connect to
# it with an msfconsole instance.  The nice thing about this interface is that
# it allows multiple clients to share one framework instance and thus makes it
# possible for sessions to to be shared from a single vantage point.
#
# $Revision: 9212 $
#

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

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

require 'msf/base'
require 'msf/ui'

# Declare the argument parser for msfd
arguments = Rex::Parser::Arguments.new(
	"-a" => [ true,  "Bind to this IP address instead of loopback"          ],
	"-p" => [ true,  "Bind to this port instead of 55554"                   ],
	"-s" => [ false, "Use SSL"                                              ],
	"-f" => [ false, "Run the daemon in the foreground"                     ],
	"-A" => [ true,  "Specify list of hosts allowed to connect"             ],
	"-D" => [ true,  "Specify list of hosts not allowed to connect"         ],
	"-h" => [ false, "Help banner"                                          ])

opts = { 'RunInForeground' => true }
foreground = false

# Parse command line arguments.
arguments.parse(ARGV) { |opt, idx, val|
	case opt
		when "-a"
			opts['ServerHost'] = val
		when "-p"
			opts['ServerPort'] = val
		when "-f"
			foreground = true
		when "-s"
			opts['SSL'] = true
		when "-A"
			begin
				opts['HostsAllowed'] = val.split(',').map { |a|
					Rex::Socket.resolv_nbo(a)
				}
			rescue
				$stderr.puts "Bad argument for -A: #{$!}"
				exit
			end
		when "-D"
			begin
				opts['HostsDenied'] = val.split(',').map { |a|
					Rex::Socket.resolv_nbo(a)
				}
			rescue
				$stderr.puts "Bad argument for -D: #{$!}"
				exit
			end
		when "-h"
			print(
				"\nUsage: #{File.basename(__FILE__)} <options>\n" +
				arguments.usage)
			exit
	end
}

$stderr.puts "[*] Initializing msfd..."

# Create an instance of the framework
$framework = Msf::Simple::Framework.create

$stderr.puts "[*] Running msfd..."

# Fork into the background if requested
begin
	if (not foreground)
		exit(0) if Process.fork()
	end
rescue ::NotImplementedError
	$stderr.puts "[-] Background mode is not available on this platform"
end

# Run the plugin instance in the foreground.
$framework.plugins.load('msfd', opts).run(opts)
