[Mimedefang] MIMEDefang Notification

Anne Bennett anne at encs.concordia.ca
Tue Dec 9 15:09:51 EST 2014

> md_check_against_smtp_server
> to verify email addresses ahead.

> This works fine for 1 destination server but in some environments there
> may be a number of servers available to authenticate against, an MS
> Exchange network for example may have multiple Hub Transport servers.

> Has anyone managed to extend this excellent logic, which works perfectly
> for single MX, to allow for multiple MX ?

Here are some excerpts from my own code (my complete code
includes local caching so I don't check back too often for
the same address - I don't show that here).  I assume that we
run the back-check only for mail being delivered locally, not
for mail on its way out.  You'll need to configure the $EC_*
variables suitably for your installation, of course.


  # Configuration: our MDAs, that we're willing to check users against:
  $EC_check_against_these_mdas = '(?:mail\d+\.encs\.concordia\.ca)';
  # A known valid sender address that we'll use for the checks:
  $EC_checker_sender_addr      = 'mail-check-back at encs.concordia.ca';

sub concordia_check_against_smtp_server($$$$)
  my ( $envsender, $rcpt_addr, $rcpt_mailer, $rcpt_host ) = @_;

  $returnval = 'CONTINUE'; # default case: fail open

  # If this isn't for SMTP delivery, cannot perform this check:
  return($returnval) unless (lc $rcpt_mailer) =~ /^e?smtp$/ ;

  # If a mailertable is in use, the $rcpt_host may be a list, so split
  # it as needed before running any checks.
  # We will check only against our own relays:
    my ( $host );
    @rcpt_hosts = ();
    foreach $host ( split /:/, $rcpt_host )
      $host =~ s/^\[(.*)\]$/$1/;  # Strip square brackets if any.
      next unless lc($host) =~ /^$EC_check_against_these_mdas$/ ; # Just ours.
      push @rcpt_hosts, $host;
  # If none of our relays were listed, we don't check:
  return($returnval) unless @rcpt_hosts;

  # Check the recipient with the next hop for this message.  The first
  # definite answer (if any) is used.  IMPORTANT: use a known good
  # sender instead of the real message's sender, otherwise a rejection
  # due to a bad sender could get cached as a rejection for the
  # recipient address! (RT#242833, 2012-04-27)
  foreach $check_mx ( @rcpt_hosts )
    my $query = $res->search($check_mx);
    # Paranoia: run only if host exists and can be resolved: 
    if ($query)
      my ( $mdc_retval, $mdc_msg ) =
          $rcpt_addr_noplus, $thishost, $check_mx);
      if ( $mdc_retval eq 'REJECT'  or  $mdc_retval eq 'CONTINUE' )
        # definitive answer, return immediately:
        return($mdc_retval, "$mdc_msg (via $check_mx)");
      # else, an error occurred, so carry on with foreach loop:
      # another MDA may be available to check this user.

    } # if the host resolves in DNS
  } # foreach check_mx

  return ($returnval); # default is CONTINUE


Hope that helps.

Ms. Anne Bennett, Senior Sysadmin, ENCS, Concordia University, Montreal H3G 1M8
anne at encs.concordia.ca                                    +1 514 848-2424 x2285

More information about the MIMEDefang mailing list