Class to send mail to a forwarding address as it is pulled over from an IMAP server. (We may want to nest this class in the MUN_IMAP module in the future.)
Messages sent to folders that match the fwd_inhibit configuration parameter are not forwarded.
Create a new forwarding object based upon the given destination address.
Get and store the mx records for the forwarded address's domain in
preparation for calling the send
method.
# File buryspam.rb, line 744 def initialize(to_addr) @to_addr = to_addr.strip @from_addr = Config.fwd_from || "" @prevent = false # The stuff after the last "@" is the domain. domain = @to_addr[/.*@(.*)/, 1] if domain.nil? raise ArgumentError, "Forwarding address: <#{@to_addr}> missing '@'" end @mx_servers = get_mx_servers(domain) @fwd_smtp_server = Config.fwd_smtp_server || "" @fwd_smtp_port = Config.fwd_smtp_port || DFLT_SMTP_PORT if @fwd_smtp_server.strip.empty? Logger.debug("No forwarding SMTP server given.") else # If supplied, we'll use the user supplied SMTP server/port as # a last resort when forwarding the message. Logger.debug("Added %s:%s to list of mail servers" % [@fwd_smtp_server, @fwd_smtp_port]) @mx_servers << [@fwd_smtp_server, @fwd_smtp_port] end # Fully qualified domain name of the local host. Used for the # HELO SMTP command. @helo_fqdn = Socket.gethostbyname(Startup::HOSTNAME).first end
Forward the given IMAP message to the destination specified by the forward-related configuration parameters.
# File buryspam.rb, line 777 def send(msg) if @prevent Logger.info("Message not forwarded.") return end servers = @mx_servers.dup server = servers.shift msg = msg.attr["RFC822"].sub(/\AReturn-Path:.*\r?\n/, "") begin # default port for all mx servers determined earlier. port = DFLT_SMTP_PORT # User specified SMTP server/port. if server.class == Array server, port = server end Logger.info("Connecting to #{server}...") Net::SMTP.start(server, port, @helo_fqdn) do |smtp| smtp.sendmail(msg, @from_addr, @to_addr) end rescue Exception => ex Logger.warn("Cannot forward to #{@to_addr} via #{server}: #{ex.message}") if servers.empty? raise "Exhausted all servers during forwarding. Giving up." end server = servers.shift retry end Logger.info("Message forwarded.") end
Return an array of the mx server names for the given domain in order of preference.
# File buryspam.rb, line 812 def get_mx_servers(domain) dns = Resolv::DNS.new mx = dns.getresources(domain, Resolv::DNS::Resource::IN::MX) mx = mx.collect {|r| [r.preference, r.exchange.to_s] }.sort records = mx.map { |rec| "\t#{rec[1]} (pref: #{rec[0]})" } Logger.debug("MX Records for '#{domain}':\n" + records.join("\n")) mx.collect{ |rec| rec[1] } end