← Back to team overview

lp-scanner-team team mailing list archive

lp:~timrchavez/lp-scanner/lp-scanner-replace-security-contact-check into lp:lp-scanner

 

Timothy R. Chavez has proposed merging lp:~timrchavez/lp-scanner/lp-scanner-replace-security-contact-check into lp:lp-scanner.

Requested reviews:
  CE Infrastructure (ce-infrastructure)

For more details, see:
https://code.launchpad.net/~timrchavez/lp-scanner/lp-scanner-replace-security-contact-check/+merge/160545

With the introduction of the sharing features in LP, the 'security_contact" field has been deprecated and removed.  I've replaced the security_contact check with a functional equivalent by determine if the project team has the Private Security permission set to 'ALL' for the project.

Note, only teams with the Private Security will be eligible to receive security notices and it is opt-in via subscriptions (so the concern about the team owner getting spammed when a security contact is not set goes away)
-- 
https://code.launchpad.net/~timrchavez/lp-scanner/lp-scanner-replace-security-contact-check/+merge/160545
Your team The Launchpad Security Scanner Dev Team is subscribed to branch lp:lp-scanner.
=== modified file 'security-scanner.py'
--- security-scanner.py	2010-12-01 23:44:52 +0000
+++ security-scanner.py	2013-04-24 04:06:26 +0000
@@ -36,6 +36,7 @@
 from launchpadlib.errors import *
 from lazr.restfulclient.errors import *
 
+
 class ConfigParser():
     """Temporarily re-implement a subset of Python's ConfigParser.
 Python 2.7 and 3.0 will have the fix for http://bugs.python.org/issue7005
@@ -49,13 +50,13 @@
 
   [allowed-owners]
   joey
-  
+
   [branch-exceptions]
   ppa
-  
+
   [bug-exceptions]
   10000
-  
+
   [ppa-exceptions]
   my-ppa-name
 
@@ -72,7 +73,7 @@
         # Maps section names to values.
         self._sections = {}
         self.section_re = re.compile("^\[([^[ ]+)\]")
-        
+
     def parse_line(self, section_name, line):
         """Parse a line as an option or option/value pair in a section.
         We do not support multi-line values (though real ConfigParser would).
@@ -208,7 +209,7 @@
     return opts, args
 
 
-def security_scanner(lp, config, outfile=None):
+def security_scanner(lp, sharing, config, outfile=None):
     """Print information about possible security leaks."""
     printf = functools.partial(print, file=outfile)
 
@@ -219,7 +220,8 @@
     bug_exceptions     = config.options('bug-exceptions')
     ppa_exceptions     = config.options('ppa-exceptions')
     allowed_mailing_lists = config.options('mailinglist-exceptions')
-    
+    nonstandard_project_teams = config.options('nonstandard-project-teams')
+
     # Traverse the project groups.
     for project_group in sorted(project_groups):
         # Collect results, so we can output them grouped and sorted (that
@@ -231,7 +233,7 @@
         public_branches = {}  # Map branch objects to project objects.
         public_bugs     = {}  # Map bug objects to project objects.
         public_ppas     = {}  # Map PPA objects to project objects.
-        unset_security  = {}  # Map project objects to None
+        project_team_private_security = {} # Map project objects to sharing policy
         exposed_mailing_lists = {}  # Map team driver to None
 
         # Get list of projects associated with the project group.
@@ -259,14 +261,24 @@
                 if (not ppa.private and
                     ppa.name not in ppa_exceptions):
                     public_ppas[ppa] = project
-            if project.security_contact is None:
-                unset_security[project] = None
+            project_team_grantee = False
+            for grantee in sharing.getPillarGranteeData(pillar=project):
+                name = grantee["name"]
+                if (name == project.name + "-team" or
+                    name in nonstandard_project_teams):
+                    project_team_grantee = True
+                    permissions = grantee["permissions"]
+                    if ("PRIVATESECURITY" not in permissions
+                        or permissions["PRIVATESECURITY"] != "ALL"):
+                        project_team_private_security[project] = None
+                    break
+            if not project_team_grantee:
+                project_team_private_security[project] = None
             # check for rogue mailing lists on the project driver
-            if project.driver.name not in allowed_mailing_lists:       
-                targeturl = "https://lists.launchpad.net/"+project.driver.name  
+            if project.driver.name not in allowed_mailing_lists:
+                targeturl = "https://lists.launchpad.net/"+project.driver.name
                 if urlopen(targeturl).getcode() != 404:
                    exposed_mailing_lists[project.driver] = None
-                  
 
         # Only print output for this project group if there were problems.
         printed_project_section_start = [False]
@@ -338,12 +350,15 @@
             footer("Those PPAs are exposed -- should any be private?")
             maybe_custom_message("public-ppas")
             printf("")
-        if unset_security:
-            header("Security Contact Not Set")
-            for key in sorted(unset_security.keys()):
-                printf("  project %s has no security contact" % key.name)
-            footer("The security contact should be set to the project team.")
-            maybe_custom_message("unset-security")
+        if project_team_private_security:
+            header("Project does not share Private Security bugs with "
+                   "project team")
+            for project in sorted(project_team_private_security.keys()):
+                printf("  project %s does not share Private Security bugs "
+                       "with the project team" % project.name)
+            footer("Project should grant access to Private Security bugs for "
+                   "the project team")
+            maybe_custom_message("project-team-private-security")
             printf("")
         if exposed_mailing_lists:
             header("Public Mailing Lists")
@@ -463,6 +478,7 @@
         sys.exit(0)
 
     lp = get_lp_instance(opts.service_name)
+    sharing = lp.load(str(lp._root_uri.append('+services/sharing')))
 
     if opts.config_files is None:
         sys.stderr.write(USAGE)
@@ -470,7 +486,7 @@
 
     config = ConfigParser()
     config.read(opts.config_files)
-    security_scanner(lp, config)
+    security_scanner(lp, sharing, config)
 
 
 if __name__ == "__main__":


Follow ups