[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[dak/master] Implement DInstall::UploadMailRecipients to control recipients of upload mails



This new setting lets you configure the list of recipients of upload
mails (Accepted/Rejected), you can mix harcoded emails and the special
keywords "maintainer", "changed_by" and "signer" which get replaced
by the corresponding address extracted from the upload data.

The goal is that the security archive only sends mails to the security
team and to the person who signed the upload to not leak any information
about embargoed uploads.

Closes: #796784
---
 config/debian-security/dak.conf |  5 ++++-
 daklib/utils.py                 | 47 +++++++++++++++++++++++++++++++++++------
 2 files changed, 44 insertions(+), 8 deletions(-)

diff --git a/config/debian-security/dak.conf b/config/debian-security/dak.conf
index 2bcfbbe..f342a55 100644
--- a/config/debian-security/dak.conf
+++ b/config/debian-security/dak.conf
@@ -18,7 +18,10 @@ Dinstall
    BXANotify "false";
    DefaultSuite "stable";
    SuiteSuffix "updates/";
-   OverrideMaintainer "dak@security.debian.org";
+   UploadMailRecipients {
+     "mail:dak@security.debian.org";
+     "signer";
+   };
    LegacyStableHasNoSections "false";
    AllowSourceOnlyUploads "true";
 };
diff --git a/daklib/utils.py b/daklib/utils.py
index 5e9c9b9..1a4b021 100644
--- a/daklib/utils.py
+++ b/daklib/utils.py
@@ -1085,15 +1085,48 @@ def mail_addresses_for_upload(maintainer, changed_by, fingerprint):
     @return: list of RFC 2047-encoded mail addresses to contact regarding
              this upload
     """
-    addresses = [maintainer]
-    if changed_by != maintainer:
-        addresses.append(changed_by)
+    recipients = Cnf.value_list('Dinstall::UploadMailRecipients')
+    if not recipients:
+        recipients = [
+            'maintainer',
+            'changed_by',
+            'signer'
+        ]
+
+    # Ensure signer is last if present
+    try:
+        recipients.pop(recipients.index('signer'))
+        recipients.append('signer')
+    except ValueError:
+        pass
+
+    # Compute the set of addresses of the recipients
+    addresses = set()  # Name + email
+    emails = set()     # Email only
+    for recipient in recipients:
+        if recipient.startswith('mail:'):  # Email hardcoded in config
+            address = recipient[5:]
+        elif recipient == 'maintainer':
+            address = maintainer
+        elif recipient == 'changed_by':
+            address = changed_by
+        elif recipient == 'signer':
+            fpr_addresses = gpg_get_key_addresses(fingerprint)
+            address = fpr_addresses[0] if len(fpr_addresses) > 0 else None
+            if any([x in emails for x in fpr_addresses]):
+                # The signer already gets a copy via another email
+                address = None
+        else:
+            raise Exception('Unsupported entry in {0}: {1}'.format(
+                'Dinstall::UploadMailRecipients', recipient))
 
-    fpr_addresses = gpg_get_key_addresses(fingerprint)
-    if len(fpr_addresses) > 0 and fix_maintainer(changed_by)[3] not in fpr_addresses and fix_maintainer(maintainer)[3] not in fpr_addresses:
-        addresses.append(fpr_addresses[0])
+        if address is not None:
+            email = fix_maintainer(address)[3]
+            if email not in emails:
+                addresses.add(address)
+                emails.add(email)
 
-    encoded_addresses = [ fix_maintainer(e)[1] for e in addresses ]
+    encoded_addresses = [fix_maintainer(e)[1] for e in addresses]
     return encoded_addresses
 
 ################################################################################
-- 
2.1.4



Reply to: