#
# Copyright (c) 2006-2021 Hal Brodigan (postmodern.mod3 at gmail.com)
#
# This file is part of ronin-support.
#
# ronin-support is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ronin-support is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with ronin-support. If not, see .
#
module Ronin
module Network
module SMTP
#
# Represents an Email to be sent over {SMTP}.
#
class Email
# The CR-LF String
CRLF = "\n\r"
# Sender of the email
attr_accessor :from
# Recipient of the email
attr_accessor :to
# Subject of the email
attr_accessor :subject
# Date of the email
attr_accessor :date
# Unique message-id string
attr_accessor :message_id
# Additional headers
attr_reader :headers
# Body of the email
attr_accessor :body
#
# Creates a new Email object.
#
# @param [Hash] options
# Additional options.
#
# @option options [String] :from
# The address the email is from.
#
# @option options [Array, String] :to
# The address that the email should be sent to.
#
# @option options [String] :subject
# The subject of the email.
#
# @option options [String] :message_id
# Message-ID of the email.
#
# @option options [String, Time] :date (Time.now)
# The date the email was sent on.
#
# @option options [Hash String}] :headers
# Additional headers.
#
# @option options [String, Array] :body
# The body of the email.
#
# @yield [email]
# If a block is given, it will be passed the newly created email
# object.
#
# @yieldparam [Email] email
# The newly created email object.
#
# @api public
#
def initialize(options={})
@from = options[:from]
@to = options[:to]
@subject = options[:subject]
@date = options.fetch(:date,Time.now)
@message_id = options[:message_id]
@headers = {}
if options[:headers]
@headers.merge!(options[:headers])
end
@body = []
if options[:body]
case options[:body]
when Array
@body += options[:body]
else
@body << options[:body]
end
end
yield self if block_given?
end
#
# Formats the email into a SMTP message.
#
# @return [String]
# Properly formatted SMTP message.
#
# @see https://rubydoc.info/stdlib/net/Net/SMTP
#
# @api public
#
def to_s
address = lambda { |info|
case info
when Array
"#{info[0]} <#{info[1]}>"
else
info
end
}
message = []
if @from
message << "From: #{@from}"
end
if @to
message << case @to
when Array
"To: #{@to.join(', ')}"
else
"To: #{@to}"
end
end
if @subject
message << "Subject: #{@subject}"
end
if @date
message << "Date: #{@date}"
end
if @message_id
message << "Message-Id: <#{@message_id}>"
end
@headers.each do |name,value|
message << "#{name}: #{value}"
end
message << ''
message += @body
return message.join(CRLF)
end
end
end
end
end