# -*- coding: binary -*-
module Msf

require 'msf/core/exploit/tcp'

###
#
# This module exposes methods that may be useful to exploits that deal with
# servers that speak the SMTP protocol.
#
###
module Exploit::Remote::Smtp

	include Exploit::Remote::Tcp

	#
	# Creates an instance of an SMTP exploit module.
	#
	def initialize(info = {})
		super

		# Register the options that all SMTP exploits may make use of.
		register_options(
			[
				Opt::RHOST,
				Opt::RPORT(25),
				OptString.new('MAILFROM', [ true, 'FROM address of the e-mail', 'zombie@brains.net']),
				OptString.new('MAILTO', [ true, 'TO address of the e-mail', 'human@ahhhzombies111.net']),
			], Msf::Exploit::Remote::Smtp)
		register_autofilter_ports([ 25, 465, 587, 2525, 25025, 25000])
		register_autofilter_services(%W{ smtp smtps})
	end

	#
	# This method establishes a SMTP connection to host and port specified by
	# the RHOST and RPORT options, respectively.  After connecting, the banner
	# message is read in and stored in the 'banner' attribute.
	#
	def connect(global = true)
		fd = super

		# Wait for a banner to arrive...
		self.banner = fd.get_once(-1, 30)
		# Return the file descriptor to the caller
		fd
	end

	#
	# Connect to the remote SMTP server, and begin a DATA transfer
	#
	def connect_login(global = true)
		smtpsock = connect(global)

		raw_send_recv("EHLO X\r\n")
		raw_send_recv("MAIL FROM: #{datastore['MAILFROM']}\r\n")
		raw_send_recv("RCPT TO: #{datastore['MAILTO']}\r\n")
		raw_send_recv("DATA\r\n")

		return true
	end

	#
	# This method transmits an IMAP command and waits for a response.  If one is
	# received, it is returned to the caller.
	#
	def raw_send_recv(cmd, nsock = self.sock)
		nsock.put(cmd)
		nsock.get_once
	end

protected

	#
	# This attribute holds the banner that was read in after a successful call
	# to connect or connect_login.
	#
	attr_accessor :banner

end

end

