Reputation: 1
I'm learning Ruby, I decided to write a postfix milter script that will modify the From: header for all emails coming to me. Here is an example of the modification: From: "Phishing domain <[email protected]>" output: "<[email protected]>". I use the ruby-milter gem: https://github.com/mstrauss/ruby-milter. My milter only works when the message is addressed to one recipient. Example: email sent to [email protected] - milter changes the From header and it works.
When there are several recipients, it doesn't work. Example: email sent to the addresses [email protected] and [email protected] - milter doesn't change the message header. Postfix logging "unexpected filter response SMFIR_CHGHEADER after event SMFIC_BODY".
EMAIL_FORMAT = /<(?<email_address>[^>]+)>/.freeze
class ModifyFromHeader < Milter::Milter
def initialize
super
@headers = {}
end
def header(name, value)
@headers[name] = [] if @headers[name].nil?
@headers[name] << value
Response.continue
end
def return_email_address(address_line)
return [] unless address_line
match_data = address_line.scan(EMAIL_FORMAT)
match_data.flatten.map(&:downcase)
end
def process_email(from_header, to_headers = [])
addresses = ["[email protected]", "[email protected]"]
email_address = return_email_address(from_header)
to_header_email_addresses = to_headers&.map do |to_header|
return_email_address(to_header)
end&.flatten || []
if to_header_email_addresses.any? { |address| ! addresses.include?(address) }
return Response.continue
end
[Response.change_header('From', email_address.to_s), Response.continue]
end
def body( _data )
from_header = @headers['From']
to_header = @headers['To']
process_email(from_header.first, to_header) unless from_header.nil? || from_header.empty?
end
end
Milter.register(ModifyFromHeader)
Milter.start(localhost, 3333)
I defined the def rcpt_to
method and moved the process_email
method to it, but this resulted in postfix logging the error: "unexpected filter response SMFIR_CHGHEADER after event SMFIC_RCPT". I also moved the process_email
method to def header
and got the message: "unexpected filter response SMFIR_CHGHEADER after event SMFIC_HEADER". I defined the def end_headers
method and moved process_email
there but to no avail: "unexpected filter response SMFIR_CHGHEADER after event SMFIC_BODY". Methods def rcpt to
, def header
, def end_headers
, def body
are methods inherited from the milter gem.
At this point I would like to limit myself to changing the header only when the message will be sent to my specific email addresses (defined in the addresses
array). I would like this to work regardless of the number of message recipients.
Example: Email will be sent to [email protected] and [email protected]. I expect the From header to change only in a message sent to [email protected]. Any ideas? What would be the "right" method? Someone guide me?
Upvotes: 0
Views: 50