You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by gb...@apache.org on 2022/03/01 08:44:20 UTC

svn commit: r1898503 - /spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/Esp.pm

Author: gbechis
Date: Tue Mar  1 08:44:20 2022
New Revision: 1898503

URL: http://svn.apache.org/viewvc?rev=1898503&view=rev
Log:
add support for Mailgun and Mdirector esp

Modified:
    spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/Esp.pm

Modified: spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/Esp.pm
URL: http://svn.apache.org/viewvc/spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/Esp.pm?rev=1898503&r1=1898502&r2=1898503&view=diff
==============================================================================
--- spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/Esp.pm (original)
+++ spamassassin/trunk/lib/Mail/SpamAssassin/Plugin/Esp.pm Tue Mar  1 08:44:20 2022
@@ -43,7 +43,7 @@ use Mail::SpamAssassin::PerMsgStatus;
 use vars qw(@ISA);
 our @ISA = qw(Mail::SpamAssassin::Plugin);
 
-my $VERSION = 1.3.0;
+my $VERSION = 1.5.0;
 
 sub dbg { Mail::SpamAssassin::Plugin::dbg ("Esp: @_"); }
 
@@ -56,14 +56,16 @@ sub new {
   bless ($self, $class);
 
   $self->set_config($mailsaobject->{conf});
+  $self->register_eval_rule('esp_constantcontact_check',  $Mail::SpamAssassin::Conf::TYPE_HEAD_EVALS);
+  $self->register_eval_rule('esp_maildome_check',  $Mail::SpamAssassin::Conf::TYPE_HEAD_EVALS);
+  $self->register_eval_rule('esp_mailchimp_check',  $Mail::SpamAssassin::Conf::TYPE_HEAD_EVALS);
+  $self->register_eval_rule('esp_mailgun_check',  $Mail::SpamAssassin::Conf::TYPE_HEAD_EVALS);
+  $self->register_eval_rule('esp_mailup_check',  $Mail::SpamAssassin::Conf::TYPE_HEAD_EVALS);
+  $self->register_eval_rule('esp_mdrctr_check',  $Mail::SpamAssassin::Conf::TYPE_HEAD_EVALS);
   $self->register_eval_rule('esp_sendgrid_check_domain',  $Mail::SpamAssassin::Conf::TYPE_HEAD_EVALS);
   $self->register_eval_rule('esp_sendgrid_check_id',  $Mail::SpamAssassin::Conf::TYPE_HEAD_EVALS);
   $self->register_eval_rule('esp_sendgrid_check',  $Mail::SpamAssassin::Conf::TYPE_HEAD_EVALS);
   $self->register_eval_rule('esp_sendinblue_check',  $Mail::SpamAssassin::Conf::TYPE_HEAD_EVALS);
-  $self->register_eval_rule('esp_mailup_check',  $Mail::SpamAssassin::Conf::TYPE_HEAD_EVALS);
-  $self->register_eval_rule('esp_maildome_check',  $Mail::SpamAssassin::Conf::TYPE_HEAD_EVALS);
-  $self->register_eval_rule('esp_mailchimp_check',  $Mail::SpamAssassin::Conf::TYPE_HEAD_EVALS);
-  $self->register_eval_rule('esp_constantcontact_check',  $Mail::SpamAssassin::Conf::TYPE_HEAD_EVALS);
 
   return $self;
 }
@@ -84,17 +86,23 @@ endif
 
 Usage:
 
+  esp_constantcontact_check()
+    Checks for Constant Contact id abused accounts
+
   esp_mailchimp_check()
     Checks for Mailchimp abused accounts
 
   esp_maildome_check()
     Checks for Maildome abused accounts
 
+  esp_mailgun_check()
+    Checks for Mailgun abused accounts
+
   esp_mailup_check()
     Checks for Mailup abused accounts
 
-  esp_sendindblue_check()
-    Checks for Sendinblue abused accounts
+  esp_mdrctr_check()
+    Checks for Mdirector id abused accounts
 
   esp_sendgrid_check()
     Checks for Sendgrid abused accounts (both id and domains)
@@ -105,30 +113,31 @@ Usage:
   esp_sendgrid_check_domain()
     Checks for Sendgrid domains abused accounts
 
-  esp_constantcontact_check()
-    Checks for Constant Contact id abused accounts
+  esp_sendindblue_check()
+    Checks for Sendinblue abused accounts
 
 =head1 ADMINISTRATOR SETTINGS
 
 =over 4
 
-=item sendgrid_feed [...]
+=item constantcontact_feed [...]
 
-A list of files with all abused Sendgrid accounts.
+A list of files with abused Constant Contact accounts.
 Files can be separated by a comma.
-More info at https://www.invaluement.com/serviceproviderdnsbl/.
-Data file can be downloaded from https://www.invaluement.com/spdata/sendgrid-id-dnsbl.txt.
 
-=item sendgrid_domains_feed [...]
+=item mailchimp_feed [...]
 
-A list of files with abused domains managed by Sendgrid.
+A list of files with abused Mailchimp accounts.
 Files can be separated by a comma.
-More info at https://www.invaluement.com/serviceproviderdnsbl/.
-Data file can be downloaded from https://www.invaluement.com/spdata/sendgrid-envelopefromdomain-dnsbl.txt.
 
-=item sendinblue_feed [...]
+=item maildome_feed [...]
 
-A list of files with abused Sendinblue accounts.
+A list of files with abused Maildome accounts.
+Files can be separated by a comma.
+
+=item mailgun_feed [...]
+
+A list of files with abused Mailgun accounts.
 Files can be separated by a comma.
 
 =item mailup_feed [...]
@@ -136,19 +145,28 @@ Files can be separated by a comma.
 A list of files with abused Mailup accounts.
 Files can be separated by a comma.
 
-=item maildome_feed [...]
+=item mdrctr_feed [...]
 
-A list of files with abused Maildome accounts.
+A list of files with abused Mdirector accounts.
 Files can be separated by a comma.
 
-=item mailchimp_feed [...]
+=item sendgrid_domains_feed [...]
 
-A list of files with abused Mailchimp accounts.
+A list of files with abused domains managed by Sendgrid.
 Files can be separated by a comma.
+More info at https://www.invaluement.com/serviceproviderdnsbl/.
+Data file can be downloaded from https://www.invaluement.com/spdata/sendgrid-envelopefromdomain-dnsbl.txt.
 
-=item constantcontact_feed [...]
+=item sendgrid_feed [...]
 
-A list of files with abused Constant Contact accounts.
+A list of files with all abused Sendgrid accounts.
+Files can be separated by a comma.
+More info at https://www.invaluement.com/serviceproviderdnsbl/.
+Data file can be downloaded from https://www.invaluement.com/spdata/sendgrid-id-dnsbl.txt.
+
+=item sendinblue_feed [...]
+
+A list of files with abused Sendinblue accounts.
 Files can be separated by a comma.
 
 =back
@@ -174,25 +192,31 @@ Tags that the plugin could set are:
 =over
 
 =item *
-SENDGRIDID
+CONSTANTCONTACTID
 
 =item *
-SENDGRIDDOM
+MAILCHIMPID
 
 =item *
-SENDINBLUEID
+MAILDOMEID
+
+=item *
+MAILGUNID
 
 =item *
 MAILUPID
 
 =item *
-MAILDOMEID
+MDRCTRID
 
 =item *
-MAILCHIMPID
+SENDGRIDDOM
 
 =item *
-CONSTANTCONTACTID
+SENDGRIDID
+
+=item *
+SENDINBLUEID
 
 =back
 
@@ -203,19 +227,25 @@ sub set_config {
   my @cmds = ();
 
   push(@cmds, {
-    setting => 'sendgrid_feed',
+    setting => 'constantcontact_feed',
     is_admin => 1,
     type => $Mail::SpamAssassin::Conf::CONF_TYPE_STRING,
     }
   );
   push(@cmds, {
-    setting => 'sendgrid_domains_feed',
+    setting => 'mailchimp_feed',
     is_admin => 1,
     type => $Mail::SpamAssassin::Conf::CONF_TYPE_STRING,
     }
   );
   push(@cmds, {
-    setting => 'sendinblue_feed',
+    setting => 'maildome_feed',
+    is_admin => 1,
+    type => $Mail::SpamAssassin::Conf::CONF_TYPE_STRING,
+    }
+  );
+  push(@cmds, {
+    setting => 'mailgun_feed',
     is_admin => 1,
     type => $Mail::SpamAssassin::Conf::CONF_TYPE_STRING,
     }
@@ -227,19 +257,25 @@ sub set_config {
     }
   );
   push(@cmds, {
-    setting => 'maildome_feed',
+    setting => 'mdrctr_feed',
     is_admin => 1,
     type => $Mail::SpamAssassin::Conf::CONF_TYPE_STRING,
     }
   );
   push(@cmds, {
-    setting => 'mailchimp_feed',
+    setting => 'sendgrid_domains_feed',
     is_admin => 1,
     type => $Mail::SpamAssassin::Conf::CONF_TYPE_STRING,
     }
   );
   push(@cmds, {
-    setting => 'constantcontact_feed',
+    setting => 'sendgrid_feed',
+    is_admin => 1,
+    type => $Mail::SpamAssassin::Conf::CONF_TYPE_STRING,
+    }
+  );
+  push(@cmds, {
+    setting => 'sendinblue_feed',
     is_admin => 1,
     type => $Mail::SpamAssassin::Conf::CONF_TYPE_STRING,
     }
@@ -249,13 +285,15 @@ sub set_config {
 
 sub finish_parsing_end {
   my ($self, $opts) = @_;
-  $self->_read_configfile('sendgrid_feed', 'SENDGRID');
+  $self->_read_configfile('constantcontact_feed', 'CONSTANTCONTACT');
+  $self->_read_configfile('mailchimp_feed', 'MAILCHIMP');
+  $self->_read_configfile('maildome_feed', 'MAILDOME');
+  $self->_read_configfile('mailgun_feed', 'MAILGUN');
+  $self->_read_configfile('mailup_feed', 'MAILUP');
+  $self->_read_configfile('mdrctr_feed', 'MDRCTR');
   $self->_read_configfile('sendgrid_domains_feed', 'SENDGRID_DOMAINS');
+  $self->_read_configfile('sendgrid_feed', 'SENDGRID');
   $self->_read_configfile('sendinblue_feed', 'SENDINBLUE');
-  $self->_read_configfile('mailup_feed', 'MAILUP');
-  $self->_read_configfile('maildome_feed', 'MAILDOME');
-  $self->_read_configfile('mailchimp_feed', 'MAILCHIMP');
-  $self->_read_configfile('constantcontact_feed', 'CONSTANTCONTACT');
 }
 
 sub _read_configfile {
@@ -289,101 +327,131 @@ sub _read_configfile {
   }
 }
 
-sub esp_sendgrid_check_domain {
+sub esp_constantcontact_check {
   my ($self, $pms) = @_;
-  my $sendgrid_id;
-  my $sendgrid_domain;
-
-  # All Sendgrid emails have the X-SG-EID header
-  my $sg_eid = $pms->get("X-SG-EID", undef);
-  return if not defined $sg_eid;
+  my $contact_id;
 
   my $rulename = $pms->get_current_eval_rule_name();
+
+  # return if X-Mailer is not what we want
+  my $xmailer = $pms->get("X-Mailer", undef);
+
+  if((not defined $xmailer) or ($xmailer !~ /Roving\sConstant\sContact/)) {
+    return;
+  }
+
   my $envfrom = $pms->get("EnvelopeFrom:addr", undef);
   return if not defined $envfrom;
+  return if $envfrom !~ /\@in\.constantcontact\.com/;
 
-  # Find the domain from the Return-Path
-  if($envfrom =~ /\@(\w+\.)?([\w\.]+)\>?$/) {
-    $sendgrid_domain = $2;
-    # dbg("ENVFROM: $envfrom domain: $sendgrid_domain");
-    if(defined $sendgrid_domain) {
-      $pms->set_tag('SENDGRIDDOM', $sendgrid_domain);
-      if ( exists $self->{ESP}->{SENDGRID_DOMAIN}->{$sendgrid_domain} ) {
-        dbg("HIT! $sendgrid_domain domain found in Sendgrid Invaluement feed");
-        $pms->test_log("Sendgrid domain: $sendgrid_domain", $rulename);
-        $pms->got_hit($rulename, "", ruletype => 'eval');
-        return 1;
-      }
+  $contact_id = $pms->get("X-Roving-Id", undef);
+  return if not defined $contact_id;
+
+  chomp($contact_id);
+  if(defined $contact_id) {
+    if ( exists $self->{ESP}->{CONSTANTCONTACT}->{$contact_id} ) {
+      $pms->set_tag('CONSTANTCONTACTID', $contact_id);
+      dbg("HIT! $contact_id customer found in Constant Contact feed");
+      $pms->test_log("Constant Contact id: $contact_id");
+      $pms->got_hit($rulename, "", ruletype => 'eval');
+      return 1;
     }
   }
 }
 
-sub esp_sendgrid_check_id {
+sub esp_mailchimp_check {
   my ($self, $pms) = @_;
-  my $sendgrid_id;
-  my $sendgrid_domain;
-
-  # All Sendgrid emails have the X-SG-EID header
-  my $sg_eid = $pms->get("X-SG-EID", undef);
-  return if not defined $sg_eid;
+  my $mailchimp_id;
 
   my $rulename = $pms->get_current_eval_rule_name();
-  my $envfrom = $pms->get("EnvelopeFrom:addr", undef);
-  return if not defined $envfrom;
 
-  # Find the customer id from the Return-Path
-  if($envfrom =~ /bounces\+(\d+)\-/) {
-    $sendgrid_id = $1;
-    # dbg("ENVFROM: $envfrom ID: $sendgrid_id");
-    if(defined $sendgrid_id) {
-      $pms->set_tag('SENDGRIDID', $sendgrid_id);
-      if ( exists $self->{ESP}->{SENDGRID}->{$sendgrid_id} ) {
-        dbg("HIT! $sendgrid_id customer id found in Sendgrid Invaluement feed");
-        $pms->test_log("Sendgrid id: $sendgrid_id", $rulename);
-        $pms->got_hit($rulename, "", ruletype => 'eval');
-        return 1;
-      }
+  # return if X-Mailer is not what we want
+  my $xmailer = $pms->get("X-Mailer", undef);
+
+  if((not defined $xmailer) or ($xmailer !~ /MailChimp Mailer/)) {
+    return;
+  }
+
+  $mailchimp_id = $pms->get("X-MC-User", undef);
+  return if not defined $mailchimp_id;
+
+  chomp($mailchimp_id);
+  if(defined $mailchimp_id) {
+    if ( exists $self->{ESP}->{MAILCHIMP}->{$mailchimp_id} ) {
+      $pms->set_tag('MAILCHIMPID', $mailchimp_id);
+      dbg("HIT! $mailchimp_id customer found in Mailchimp feed");
+      $pms->test_log("Mailchimp id: $mailchimp_id");
+      $pms->got_hit($rulename, "", ruletype => 'eval');
+      return 1;
     }
   }
 }
 
-sub esp_sendgrid_check {
+sub esp_maildome_check {
   my ($self, $pms) = @_;
+  my $maildome_id;
 
-  my $ret;
+  my $rulename = $pms->get_current_eval_rule_name();
 
-  $ret = $self->esp_sendgrid_check_id($pms);
-  if (!$ret) {
-    $ret = $self->esp_sendgrid_check_domain($pms);
+  # return if X-Mailer is not what we want
+  my $xmailer = $pms->get("X-Mailer", undef);
+
+  if((not defined $xmailer) or ($xmailer !~ /MaildomeMTA/)) {
+    return;
+  }
+
+  $maildome_id = $pms->get("List-Unsubscribe", undef);
+  return if not defined $maildome_id;
+  $maildome_id =~ /subject=https:\/\/.*\/unsubscribe\/([0-9]+)\/([0-9]+)\/.*\/([0-9]+)\/([0-9]+)\>/;
+  $maildome_id = $2;
+
+  # if regexp doesn't match it's not Maildome
+  return if not defined $maildome_id;
+  chomp($maildome_id);
+  if(defined $maildome_id) {
+    if ( exists $self->{ESP}->{MAILDOME}->{$maildome_id} ) {
+      $pms->set_tag('MAILDOMEID', $maildome_id);
+      dbg("HIT! $maildome_id customer found in Maildome feed");
+      $pms->test_log("Maildome id: $maildome_id");
+      $pms->got_hit($rulename, "", ruletype => 'eval');
+      return 1;
+    }
   }
-  return $ret;
 }
 
-sub esp_sendinblue_check {
+sub esp_mailgun_check {
   my ($self, $pms) = @_;
-  my $sendinblue_id;
+  my $mailgun_id;
 
   my $rulename = $pms->get_current_eval_rule_name();
-  my $envfrom = $pms->get("EnvelopeFrom:addr", undef);
-  # All Sendinblue emails have the X-Mailer header set to Sendinblue
+
+  # Mailgun doesn't define an X-Mailer header
   my $xmailer = $pms->get("X-Mailer", undef);
-  if((not defined $xmailer) or ($xmailer !~ /Sendinblue/)) {
+  if(defined $xmailer) {
     return;
   }
 
-  $sendinblue_id = $pms->get("X-Mailin-Client", undef);
-  return if not defined $sendinblue_id;
-  chomp($sendinblue_id);
-  if(defined $sendinblue_id) {
-    if ( exists $self->{ESP}->{SENDINBLUE}->{$sendinblue_id} ) {
-      $pms->set_tag('SENDINBLUEID', $sendinblue_id);
-      dbg("HIT! $sendinblue_id ID found in Sendinblue feed");
-      $pms->test_log("Sendinblue id: $sendinblue_id", $rulename);
+  my $xsendip = $pms->get("X-Mailgun-Sending-Ip", undef);
+  if(not defined $xsendip) {
+    return;
+  }
+
+  my $envfrom = $pms->get("EnvelopeFrom:addr", undef);
+  return if not defined $envfrom;
+  # Find the customer id from the Return-Path
+  $envfrom =~ /bounce\+(\w+)\.(\w+)\-/;
+  $mailgun_id = $2;
+
+  if(defined $mailgun_id) {
+    chomp($mailgun_id);
+    if ( exists $self->{ESP}->{MAILGUN}->{$mailgun_id} ) {
+      $pms->set_tag('MAILGUN', $mailgun_id);
+      dbg("HIT! $mailgun_id customer found in Mailgun feed");
+      $pms->test_log("Mailgun id: $mailgun_id");
       $pms->got_hit($rulename, "", ruletype => 'eval');
       return 1;
     }
   }
-
 }
 
 sub esp_mailup_check {
@@ -416,106 +484,137 @@ sub esp_mailup_check {
     if ( exists $self->{ESP}->{MAILUP}->{$mailup_id} ) {
       $pms->set_tag('MAILUPID', $mailup_id);
       dbg("HIT! $mailup_id customer found in Mailup feed");
-      $pms->test_log("Mailup id: $mailup_id", $rulename);
+      $pms->test_log("Mailup id: $mailup_id");
       $pms->got_hit($rulename, "", ruletype => 'eval');
       return 1;
     }
   }
+}
+
+sub esp_sendgrid_check {
+  my ($self, $pms) = @_;
+
+  my $ret;
 
+  $ret = $self->esp_sendgrid_check_id($pms);
+  if (!$ret) {
+    $ret = $self->esp_sendgrid_check_domain($pms);
+  }
+  return $ret;
 }
 
-sub esp_maildome_check {
+sub esp_sendgrid_check_domain {
   my ($self, $pms) = @_;
-  my $maildome_id;
+  my $sendgrid_id;
+  my $sendgrid_domain;
 
-  my $rulename = $pms->get_current_eval_rule_name();
+  # All Sendgrid emails have the X-SG-EID header
+  my $sg_eid = $pms->get("X-SG-EID", undef);
+  return if not defined $sg_eid;
 
-  # return if X-Mailer is not what we want
-  my $xmailer = $pms->get("X-Mailer", undef);
+  my $rulename = $pms->get_current_eval_rule_name();
+  my $envfrom = $pms->get("EnvelopeFrom:addr", undef);
+  return if not defined $envfrom;
 
-  if((not defined $xmailer) or ($xmailer !~ /MaildomeMTA/)) {
-    return;
+  # Find the domain from the Return-Path
+  if($envfrom =~ /\@(\w+\.)?([\w\.]+)\>?$/) {
+    $sendgrid_domain = $2;
+    # dbg("ENVFROM: $envfrom domain: $sendgrid_domain");
+    if(defined $sendgrid_domain) {
+      $pms->set_tag('SENDGRIDDOM', $sendgrid_domain);
+      if ( exists $self->{ESP}->{SENDGRID_DOMAIN}->{$sendgrid_domain} ) {
+        dbg("HIT! $sendgrid_domain domain found in Sendgrid Invaluement feed");
+        $pms->test_log("Sendgrid domain: $sendgrid_domain");
+        $pms->got_hit($rulename, "", ruletype => 'eval');
+        return 1;
+      }
+    }
   }
+}
 
-  $maildome_id = $pms->get("List-Unsubscribe", undef);
-  return if not defined $maildome_id;
-  $maildome_id =~ /subject=https:\/\/.*\/unsubscribe\/([0-9]+)\/([0-9]+)\/.*\/([0-9]+)\/([0-9]+)\>/;
-  $maildome_id = $2;
+sub esp_sendgrid_check_id {
+  my ($self, $pms) = @_;
+  my $sendgrid_id;
+  my $sendgrid_domain;
 
-  # if regexp doesn't match it's not Maildome
-  return if not defined $maildome_id;
-  chomp($maildome_id);
-  if(defined $maildome_id) {
-    if ( exists $self->{ESP}->{MAILDOME}->{$maildome_id} ) {
-      $pms->set_tag('MAILDOMEID', $maildome_id);
-      dbg("HIT! $maildome_id customer found in Maildome feed");
-      $pms->test_log("Maildome id: $maildome_id", $rulename);
-      $pms->got_hit($rulename, "", ruletype => 'eval');
-      return 1;
+  # All Sendgrid emails have the X-SG-EID header
+  my $sg_eid = $pms->get("X-SG-EID", undef);
+  return if not defined $sg_eid;
+
+  my $rulename = $pms->get_current_eval_rule_name();
+  my $envfrom = $pms->get("EnvelopeFrom:addr", undef);
+  return if not defined $envfrom;
+
+  # Find the customer id from the Return-Path
+  if($envfrom =~ /bounces\+(\d+)\-/) {
+    $sendgrid_id = $1;
+    # dbg("ENVFROM: $envfrom ID: $sendgrid_id");
+    if(defined $sendgrid_id) {
+      $pms->set_tag('SENDGRIDID', $sendgrid_id);
+      if ( exists $self->{ESP}->{SENDGRID}->{$sendgrid_id} ) {
+        dbg("HIT! $sendgrid_id customer id found in Sendgrid Invaluement feed");
+        $pms->test_log("Sendgrid id: $sendgrid_id");
+        $pms->got_hit($rulename, "", ruletype => 'eval');
+        return 1;
+      }
     }
   }
-
 }
 
-sub esp_mailchimp_check {
+sub esp_sendinblue_check {
   my ($self, $pms) = @_;
-  my $mailchimp_id;
+  my $sendinblue_id;
 
   my $rulename = $pms->get_current_eval_rule_name();
-
-  # return if X-Mailer is not what we want
+  my $envfrom = $pms->get("EnvelopeFrom:addr", undef);
+  # All Sendinblue emails have the X-Mailer header set to Sendinblue
   my $xmailer = $pms->get("X-Mailer", undef);
-
-  if((not defined $xmailer) or ($xmailer !~ /MailChimp Mailer/)) {
+  if((not defined $xmailer) or ($xmailer !~ /Sendinblue/)) {
     return;
   }
 
-  $mailchimp_id = $pms->get("X-MC-User", undef);
-  return if not defined $mailchimp_id;
-
-  chomp($mailchimp_id);
-  if(defined $mailchimp_id) {
-    if ( exists $self->{ESP}->{MAILCHIMP}->{$mailchimp_id} ) {
-      $pms->set_tag('MAILCHIMPID', $mailchimp_id);
-      dbg("HIT! $mailchimp_id customer found in Mailchimp feed");
-      $pms->test_log("Mailchimp id: $mailchimp_id", $rulename);
+  $sendinblue_id = $pms->get("X-Mailin-Client", undef);
+  return if not defined $sendinblue_id;
+  chomp($sendinblue_id);
+  if(defined $sendinblue_id) {
+    if ( exists $self->{ESP}->{SENDINBLUE}->{$sendinblue_id} ) {
+      $pms->set_tag('SENDINBLUEID', $sendinblue_id);
+      dbg("HIT! $sendinblue_id ID found in Sendinblue feed");
+      $pms->test_log("Sendinblue id: $sendinblue_id");
       $pms->got_hit($rulename, "", ruletype => 'eval');
       return 1;
     }
   }
-
 }
 
-sub esp_constantcontact_check {
+sub esp_mdrctr_check {
   my ($self, $pms) = @_;
-  my $contact_id;
+  my $mdrctr_id;
 
-  my $rulename = $pms->get_current_eval_rule_name();
-
-  # return if X-Mailer is not what we want
-  my $xmailer = $pms->get("X-Mailer", undef);
+  # All Sendgrid emails have the X-ElasticEmail-Postback header
+  my $sg_eid = $pms->get("X-ElasticEmail-Postback", undef);
+  return if not defined $sg_eid;
 
-  if((not defined $xmailer) or ($xmailer !~ /Roving\sConstant\sContact/)) {
-    return;
-  }
+  my $rulename = $pms->get_current_eval_rule_name();
+  my $fid = $pms->get("Feedback-ID", undef);
+  return if not defined $fid;
 
   my $envfrom = $pms->get("EnvelopeFrom:addr", undef);
-  return if not defined $envfrom;
-  return if $envfrom !~ /\@in\.constantcontact\.com/;
+  return if ($envfrom !~ /bounces\.mdrctr\.com/);
 
-  $contact_id = $pms->get("X-Roving-Id", undef);
-  return if not defined $contact_id;
-
-  chomp($contact_id);
-  if(defined $contact_id) {
-    if ( exists $self->{ESP}->{CONSTANTCONTACT}->{$contact_id} ) {
-      $pms->set_tag('CONSTANTCONTACTID', $contact_id);
-      dbg("HIT! $contact_id customer found in Constant Contact feed");
-      $pms->test_log("Constant Contact id: $contact_id", $rulename);
-      $pms->got_hit($rulename, "", ruletype => 'eval');
-      return 1;
+  # Find the customer id from the Return-Path
+  if($fid =~ /(\d+)\:(\d+)\:([a-z]+)/i) {
+    $mdrctr_id = $1;
+    if(defined $mdrctr_id) {
+      $pms->set_tag('MDRCTRID', $mdrctr_id);
+      if ( exists $self->{ESP}->{MDRCTR}->{$mdrctr_id} ) {
+        dbg("HIT! $mdrctr_id customer id found in Mdirector feed");
+        $pms->test_log("Mdirector id: $mdrctr_id", $rulename);
+        $pms->got_hit($rulename, "", ruletype => 'eval');
+        return 1;
+      }
     }
   }
-
 }
+
 1;