]> git.decadent.org.uk Git - dak.git/commitdiff
mail-whitelist
authorJoerg Jaspert <joerg@debian.org>
Fri, 13 Feb 2009 21:04:48 +0000 (22:04 +0100)
committerJoerg Jaspert <joerg@debian.org>
Fri, 13 Feb 2009 21:04:48 +0000 (22:04 +0100)
finally make the mail whitelist patch a proper part of dak.

Signed-off-by: Joerg Jaspert <joerg@debian.org>
config/debian/dak.conf
daklib/utils.py

index 345565b3e2b18f631bb0548a02ecab45658efad8..00f0bd1ab294f52450fc08bf7ea926180706ccd5 100644 (file)
@@ -35,6 +35,14 @@ Dinstall
      NoSourceOnly "true";
      ReleaseTransitions "/srv/ftp.debian.org/web/transitions.yaml";
    };
+   // if you setup an own dak repository and want to upload Debian packages you most possibly want
+   // to set the following option to a real path/filename and then enter those mail addresses that
+   // you want to be able to receive mails generated by your dak installation. This avoids spamming
+   // the real maintainers of a package you upload with mail.
+   // format of entries: one entry per line. Either an email address directly, or a regular expression,
+   // prefixed by "RE:". Examples: "jane.doe@domain.com" or "RE:jane[^@]@domain.com", where the first will
+   // only allow to mail jane.doe@domain.com while the second will mail all of jane*@domain.com
+   //  MailWhiteList "/some/path/to/a/file";
 };
 
 Transitions
index 7b822b9db312f3adb965bf3db4e586925c141db6..85ef0b5573b86649c1e57030c37332d4263e6b7f 100755 (executable)
@@ -37,6 +37,7 @@ import stat
 import apt_pkg
 import database
 import time
+import email as modemail
 from dak_exceptions import *
 from regexes import re_html_escaping, html_escaping, re_single_line_field, \
                     re_multi_line_field, re_srchasver, re_verwithext, \
@@ -598,6 +599,68 @@ def send_mail (message, filename=""):
         os.write (fd, message)
         os.close (fd)
 
+    if Cnf.has_key("Dinstall::MailWhiteList") and \
+           Cnf["Dinstall::MailWhiteList"] != "":
+        message_in = open_file(filename)
+        message_raw = modemail.message_from_file(message_in)
+        message_in.close();
+
+        whitelist = [];
+        whitelist_in = open_file(Cnf["Dinstall::MailWhiteList"])
+        RE_mark = re.compile(r'^RE:')
+        try:
+            for line in whitelist_in:
+                if RE_mark.match(line):
+                    whitelist.append(re.compile(RE_mark.sub("", line.strip(), 1)))
+                else:
+                    whitelist.append(re.compile(re.escape(line.strip())))
+        finally:
+            whitelist_in.close()
+
+        # Fields to check.
+        fields = ["To", "Bcc", "Cc"]
+        for field in fields:
+            # Check each field
+            value = message_raw.get(field, None)
+            if value != None:
+                match = [];
+                for item in value.split(","):
+                    (rfc822_maint, rfc2047_maint, name, email) = fix_maintainer(item.strip())
+                    mail_whitelisted = 0
+                    for wr in whitelist:
+                        if wr.match(email):
+                            mail_whitelisted = 1
+                            break
+                    if not mail_whitelisted:
+                        print "Skipping %s since it's not in %s" % (item, Cnf["Dinstall::MailWhiteList"])
+                        continue
+                    match.append(item)
+
+                # Doesn't have any mail in whitelist so remove the header
+                if len(match) == 0:
+                    del message_raw[field]
+                else:
+                    message_raw.replace_header(field, string.join(match, ", "))
+
+        # Change message fields in order if we don't have a To header
+        if not message_raw.has_key("To"):
+            fields.reverse()
+            for field in fields:
+                if message_raw.has_key(field):
+                    message_raw[fields[-1]] = message_raw[field]
+                    del message_raw[field]
+                    break
+            else:
+                # Clean up any temporary files
+                # and return, as we removed all recipients.
+                if message:
+                    os.unlink (filename);
+                return;
+
+        fd = os.open(filename, os.O_RDWR|os.O_EXCL, 0700);
+        os.write (fd, message_raw.as_string(True));
+        os.close (fd);
+
     # Invoke sendmail
     (result, output) = commands.getstatusoutput("%s < %s" % (Cnf["Dinstall::SendmailCommand"], filename))
     if (result != 0):