Author: fw Date: 2011-04-24 17:37:45 +0000 (Sun, 24 Apr 2011) New Revision: 16587 Added: bin/gen-DSA.py Log: bin/gen_DSA.py: reimplementation of bin/gen-DSA in Python Should have feature parity with the existing Shell script. Added: bin/gen-DSA.py ==================================================================--- bin/gen-DSA.py (rev 0) +++ bin/gen-DSA.py 2011-04-24 17:37:45 UTC (rev 16587) @@ -0,0 +1,202 @@ +#!/usr/bin/python +# gen-DSA -- create a DSA template +# Copyright (C) 2011 Florian Weimer <fw at deneb.enyo.de> +# +# User interface based on a shell version written by +# Raphael Geissert <geissert at debian.org>. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +# This script is intended to be run on security-master to get an +# unprocessed dump of the contents of the embargoed and unembargoed +# queues. +# +# The script reads .deb and .changes files. A caching database is +# written to ~/.cache. + + +import sys +import os.path +def setup_path(): + dirname = os.path.dirname + base = dirname(dirname(os.path.realpath(sys.argv[0]))) + sys.path.insert(0, os.path.join(base, "lib", "python")) +setup_path() + +from pwd import getpwuid +import re +import time + +import debian_support +import bugs + +def parsecommand(): + args = sys.argv[1:] + if not args: + usage() + + global opt_save + if args[0] == "--save": + opt_save = True + del args[0] + else: + opt_save = False + if len(args) < 3: + usage() + + global opt_dsaid + opt_dsaid = args[0] + if opt_dsaid.upper().startswith("DSA-"): + opt_dsaid = opt_dsaid[4:] + if "-" not in opt_dsaid: + opt_dsaid += "-1" + + global opt_package + opt_package = args[1] + if not opt_package: + usage("package argument is empty") + + global opt_vulnerability + opt_vulnerability = args[2] + if not opt_vulnerability: + usage("vulnerability argument is empty") + + global opt_cve + if len(args) >= 4: + re_cve = re.compile("(?i)CVE-\d{4}-\d{4,}") + opt_cve = set() + for cve in args[3].split(): + if not cve: + continue + cve = cve.upper() + if not re_cve.match(cve): + usage("malformed CVE name: " + repr(cve)) + if cve in opt_cve: + usage("duplicate CVE: " + repr(cve)) + opt_cve.add(cve) + opt_cve = tuple(sorted(opt_cve)) + else: + opt_cve = () + + global opt_bugs + if len(args) >= 5: + opt_bugs = set() + for bug in args[3].split(): + if not bug: + continue + try: + bug = int(bug) + if bug <= 0: + raise ValueError + except: + usage("malformed bug number: " + repr(bug)) + if bug in opt_bugs: + usage("duplicate bug number: " + repr(bug)) + opt_bugs.add(cve) + opt_bugs = tuple(sorted(opt_bugs)) + else: + opt_bugs = () + if len(args) >= 5: + usage() + +def usage(msg=None): + if msg is not None: + print >>sys.stderr, "error:", msg + print >>sys.stderr, "usage:", sys.argv[0], \ + "[--save] DSA package vulnerability [CVE [bug number]]" + print >>sys.stderr + print >>sys.stderr, \ + "Multiple CVE and bug numbers can be separated by spaces" + sys.exit(1) + +def gecos(): + gecos = os.getenv("DEBFULLNAME") + if gecos is not None: + return gecos + gecos = getpwuid(os.getuid()).pw_gecos + return gecos.split(",")[0] + +def debemail(): + for env in ("DEBEMAIL", "USER"): + email = os.getenv(env) + if email is not None: + return email + return "unknown" + +def filledtemplate(values, re_var=re.compile(r"\$\$?([A-Z_]+)")): + template = file(debian_support.findresource("doc", "DSA.template")).read() + def repl(match): + return values[match.group(1)] + return re_var.sub(repl, template) + +tm = time.gmtime(time.time()) +def getdate(months=" January February March April May June July August September October November December".split()): + return "{0} {1:0}, {2}".format(months[tm.tm_mon], tm.tm_mday, tm.tm_year) + +dsa_list_path = debian_support.findresource(*"data DSA list".split()) +def checklist(): + name = "DSA-" + opt_dsaid + for bug in bugs.DSAFile(dsa_list_path): + if bug.name == name or (bug.name + "-1") == name: + print >>sys.stderr, "DSA already exists:", repr(opt_dsaid) + sys.exit(1) + +def newdsalist(months=" Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split()): + lines = ["[{0:0} {1} {2}] DSA-{3} {4} - {5}\n".format( + tm.tm_mday, months[tm.tm_mon], tm.tm_year, + opt_dsaid, opt_package, opt_vulnerability)] + if opt_cve: + lines.append("\t{" + " ".join(opt_cve) + "}\n") + lines = lines + list(file(dsa_list_path)) + return lines + +def checkfile(): + global dsa_file + dsa_file = "DSA-" + opt_dsaid + if os.path.exists(dsa_file): + print >>sys.stderr, "DSA file already exists:", repr(dsa_file) + sys.exit(1) + +parsecommand() +checklist() +checkfile() +template = filledtemplate({ + "DEBFULLNAME" : gecos(), + "DEBEMAIL" : debemail(), + "DSAID" : opt_dsaid, + "PACKAGE" : opt_package, + "SPACEDDATE" : getdate().ljust(22), + "VULNERABILITY" : opt_vulnerability, + "REMLOCAL" : os.getenv("REMLOCAL", "remote"), + "DEBIANSPECIFIC" : os.getenv("DEBIANSPECIFIC", "no"), + "CVE" : " ".join(opt_cve), + "BUGNUM" : " ".join(opt_bugs), + "OLDSTABLE" : debian_support.releasecodename("oldstable"), + "STABLE" : debian_support.releasecodename("stable"), + "TESTING" : debian_support.releasecodename("testing"), + "OLDSTABLE_VERSION" : "$OLDSTABLE_VERSION", + "STABLE_VERSION" : "$STABLE_VERSION", + "TESTING_VERSION" : "$TESTING_VERSION", + "UNSTABLE_VERSION" : "$UNSTABLE_VERSION", + "SPACEDDEBFULLNAME" : gecos().rjust(24), + }) +if opt_save: + updatedlist = newdsalist() + out = file(dsa_file, "w+") + out.write(template) + out.close() + debian_support.replaceFile(updatedlist, dsa_list_path) +else: + print template, Property changes on: bin/gen-DSA.py ___________________________________________________________________ Added: svn:executable + *