Patch Majordomo to work with DMARC

Note: This patch and related changes isn't strictly RFC compliant. However, seeing as how DMARC is breaking email so badly, this is needed and is considered an acceptable work around by many. This is one of the acceptable work-around in the Mailman 2.1.6 and above. I'd love to hear objective technical alternatives to this method in the comments below.

What does this Majordomo patch do?

This patch fixes Majordomo by doing three things:

  1. Change the email From: header to be the email address of the list itself
  2. Add a new variable to Majordomo to allow enabling on a list-by-list basis
  3. Add the Reply-to: header with the email address of the author 

Apply this patch to `resend`:

--- resend_NoPatch 2018-11-09 13:35:25.805478789 -0800
+++ resend 2018-11-09 13:43:01.473792789 -0800
@@ -176,6 +176,8 @@ $opt_s = &cf_ck_bool($opt_l,"administriv
  if &cf_ck_bool($opt_l,"administrivia");
 $opt_d = &cf_ck_bool($opt_l,"debug")
  if &cf_ck_bool($opt_l,"debug");
+$opt_D = &cf_ck_bool($opt_l,"resend_dmarc")
+            if &cf_ck_bool($opt_l,"resend_dmarc");
 # Construct the envelope sender for outbound messages
 if (defined($opt_f)) {
@@ -354,6 +356,24 @@ open(IN, "$TMPDIR/resend.$$.in") ||
 # Message parsing starts here
 #
+## First get the "To: and capture the address... DMARC adds
+print STDERR "$0: find To:.\n" if $DEBUG;
+while (<IN>) {
+    ## added to capture the list address for use as From; 'cause of DMARC stuff.
+    if (/^To:\s*(.*)/i && defined($opt_D)) {
+        $newfrom = $_;
+        print STDERR "$0: New From Before $newfrom\n" if $DEBUG;
+        $newfrom =~ s/^To: //;
+        print STDERR "$0: New From After  $newfrom\n" if $DEBUG;
+    }
+}
+close(IN);
+
+open(IN, "$TMPDIR/resend.$$.in") ||
+    die("resend: Can't open $TMPDIR/resend.$$.tmp: $!");
+###  end of DMARC changes
+
+
 print STDERR "$0: parsing header.\n" if $DEBUG;
 # parse the header for bad lines, etc.  We'll bounce in a moment.
@@ -512,6 +532,14 @@ open(MAILIN, "$TMPDIR/resend.$$.out");
 # spit it out!
 #
 while (<MAILIN>) {
+    ## Change From to value of To (in $newfrom) 'cause of DMARC
+    print STDERR "$0: Var resend_dmarc: $opt_D\n" if $DEBUG;
+    if (/^From:\s*(.+)/i && defined($opt_D)) {
+        ### change from to value of To: 'cause of DMARC...
+        print STDERR "$0: before From: $_\n" if $DEBUG;
+        $_ = "From: $newfrom";
+        print STDERR "$0: after From: $_\n" if $DEBUG;
+    }
     print MAILOUT $_;
 }

Apply this patch to `config_parse.pl`:

--- /usr/local/src/majordomo-1.94.5/config_parse.pl 2000-01-07 09:00:26.000000000 -0500
+++ config_parse.pl 2018-11-07 21:44:47.254899954 -0500
@@ -76,6 +76,7 @@ $installing_defaults = 0; # Set to 1 whe
 # otherwise the value is the default value for the keyword.
 # if the value starts with #!, the rest of the value is eval'ed
 %known_keys = (
+    'resend_dmarc',   'no', # rewrite sender to be list to get around DMARC issues
  'welcome', 'yes', # send welcome msg to new subscribers
  'announcements', 'yes', # send sub/unsub audits to list owner
  'get_access', "open\001closed\001list\001list", # open, anyone can access
@@ -147,6 +148,9 @@ $installing_defaults = 0; # Set to 1 whe
 # An associative array of comments for all of the keys
 # The text is wrapped and filled on output.
 %comments = (
+'resend_dmarc',
+"Set to yes if you want this list to rewrite the From address to be
+the address of the mailing list.",
 'welcome',
 "If set to yes, a welcome message (and optional 'intro' file) will be
 sent to the newly subscribed user.",
@@ -441,6 +445,7 @@ the queue exceeds this number of days.",
  'date_intro', 'majordomo',
  'archive_dir', 'majordomo',
 # stuff for resend below
+        'resend_dmarc', 'resend',
         'moderate', 'resend',
         'moderator', 'resend',
         'approve_passwd', 'resend',
@@ -497,6 +502,7 @@ the queue exceeds this number of days.",
  'date_intro', 'grab_bool',
  'archive_dir', 'grab_absolute_dir',
 # stuff for resend below
+        'resend_dmarc', 'grab_bool',
         'moderate', 'grab_bool',
         'moderator', 'grab_word',
         'approve_passwd',  'grab_word',

Finally, make the following changes to any list you wish to enable this patch for.

Add the follow variable to your mailinglist.config file:

resend_dmarc = yes

Modify the reply_to variable to:

reply_to = $SENDER

Have a better solution? Please share in the comments.

Comments