tajgerON
tajgerON

Reputation: 1

Ruby Milter why do I have unexpected SMFIR_CHGHEADER filter response after SMFIC_BODY event

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

Answers (0)

Related Questions