aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'portage_with_autodep/bin/glsa-check')
-rwxr-xr-xportage_with_autodep/bin/glsa-check196
1 files changed, 107 insertions, 89 deletions
diff --git a/portage_with_autodep/bin/glsa-check b/portage_with_autodep/bin/glsa-check
index a840c32..7fa3688 100755
--- a/portage_with_autodep/bin/glsa-check
+++ b/portage_with_autodep/bin/glsa-check
@@ -1,81 +1,79 @@
#!/usr/bin/python
-# Copyright 2008-2011 Gentoo Foundation
+# Copyright 2008-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
from __future__ import print_function
import sys
+import codecs
-try:
- import portage
-except ImportError:
- from os import path as osp
- sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
- import portage
-
+from os import path as osp
+pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
+sys.path.insert(0, pym_path)
+import portage
+portage._internal_caller = True
from portage import os
-from portage.output import *
-
-from optparse import OptionGroup, OptionParser
+from portage.output import green, red, nocolor, white
+from portage.util._argparse import ArgumentParser
__program__ = "glsa-check"
__author__ = "Marius Mauch <genone@gentoo.org>"
__version__ = "1.0"
-def cb_version(*args, **kwargs):
- """Callback for --version"""
- sys.stderr.write("\n"+ __program__ + ", version " + __version__ + "\n")
- sys.stderr.write("Author: " + __author__ + "\n")
- sys.stderr.write("This program is licensed under the GPL, version 2\n\n")
- sys.exit(0)
-
# option parsing
-parser = OptionParser(usage="%prog <option> [glsa-list]",
- version="%prog "+ __version__)
-parser.epilog = "glsa-list can contain an arbitrary number of GLSA ids," \
+epilog = "glsa-list can contain an arbitrary number of GLSA ids," \
" filenames containing GLSAs or the special identifiers" \
" 'all', 'new' and 'affected'"
+parser = ArgumentParser(usage=__program__ + " <option> [glsa-list]",
+ epilog=epilog)
-modes = OptionGroup(parser, "Modes")
-modes.add_option("-l", "--list", action="store_const",
+modes = parser.add_argument_group("Modes")
+modes.add_argument("-l", "--list", action="store_const",
const="list", dest="mode",
help="List all unapplied GLSA")
-modes.add_option("-d", "--dump", action="store_const",
+modes.add_argument("-d", "--dump", action="store_const",
const="dump", dest="mode",
help="Show all information about the given GLSA")
-modes.add_option("", "--print", action="store_const",
+modes.add_argument("--print", action="store_const",
const="dump", dest="mode",
help="Alias for --dump")
-modes.add_option("-t", "--test", action="store_const",
+modes.add_argument("-t", "--test", action="store_const",
const="test", dest="mode",
help="Test if this system is affected by the given GLSA")
-modes.add_option("-p", "--pretend", action="store_const",
+modes.add_argument("-p", "--pretend", action="store_const",
const="pretend", dest="mode",
help="Show the necessary commands to apply this GLSA")
-modes.add_option("-f", "--fix", action="store_const",
+modes.add_argument("-f", "--fix", action="store_const",
const="fix", dest="mode",
help="Try to auto-apply this GLSA (experimental)")
-modes.add_option("-i", "--inject", action="store_const", dest="mode",
- help="Inject the given GLSA into the checkfile")
-modes.add_option("-m", "--mail", action="store_const",
+modes.add_argument("-i", "--inject", action="store_const",
+ const="inject", dest="mode",
+ help="inject the given GLSA into the glsa_injected file")
+modes.add_argument("-m", "--mail", action="store_const",
const="mail", dest="mode",
help="Send a mail with the given GLSAs to the administrator")
-parser.add_option_group(modes)
-parser.remove_option("--version")
-parser.add_option("-V", "--version", action="callback",
- callback=cb_version, help="Some information about this tool")
-parser.add_option("-v", "--verbose", action="store_true", dest="verbose",
+parser.add_argument("-V", "--version", action="store_true",
+ help="Some information about this tool")
+parser.add_argument("-v", "--verbose", action="store_true", dest="verbose",
help="Print more information")
-parser.add_option("-n", "--nocolor", action="callback",
- callback=lambda *args, **kwargs: nocolor(),
+parser.add_argument("-n", "--nocolor", action="store_true",
help="Disable colors")
-parser.add_option("-e", "--emergelike", action="store_false", dest="least_change",
+parser.add_argument("-e", "--emergelike", action="store_false", dest="least_change",
help="Do not use a least-change algorithm")
-parser.add_option("-c", "--cve", action="store_true", dest="list_cve",
+parser.add_argument("-c", "--cve", action="store_true", dest="list_cve",
help="Show CAN ids in listing mode")
-options, params = parser.parse_args()
+options, params = parser.parse_known_args()
+
+if options.nocolor:
+ nocolor()
+
+if options.version:
+ sys.stderr.write("\n"+ __program__ + ", version " + __version__ + "\n")
+ sys.stderr.write("Author: " + __author__ + "\n")
+ sys.stderr.write("This program is licensed under the GPL, version 2\n\n")
+ sys.exit(0)
mode = options.mode
least_change = options.least_change
@@ -101,7 +99,8 @@ elif mode == "list" and not params:
params.append("new")
# delay this for speed increase
-from portage.glsa import *
+from portage.glsa import (Glsa, GlsaTypeException, GlsaFormatException,
+ get_applied_glsas, get_glsa_list)
eroot = portage.settings['EROOT']
vardb = portage.db[eroot]["vartree"].dbapi
@@ -117,7 +116,7 @@ glsalist = []
if "new" in params:
glsalist = todolist
params.remove("new")
-
+
if "all" in params:
glsalist = completelist
params.remove("all")
@@ -142,8 +141,17 @@ for p in params[:]:
glsalist.extend([g for g in params if g not in glsalist])
-def summarylist(myglsalist, fd1=sys.stdout, fd2=sys.stderr):
- fd2.write(white("[A]")+" means this GLSA was already applied,\n")
+def summarylist(myglsalist, fd1=sys.stdout, fd2=sys.stderr, encoding="utf-8"):
+ # Get to the raw streams in py3k before wrapping them with an encoded writer
+ # to avoid writing bytes to a text stream (stdout/stderr are text streams
+ # by default in py3k)
+ if hasattr(fd1, "buffer"):
+ fd1 = fd1.buffer
+ if hasattr(fd2, "buffer"):
+ fd2 = fd2.buffer
+ fd1 = codecs.getwriter(encoding)(fd1)
+ fd2 = codecs.getwriter(encoding)(fd2)
+ fd2.write(white("[A]")+" means this GLSA was marked as applied (injected),\n")
fd2.write(green("[U]")+" means the system is not affected and\n")
fd2.write(red("[N]")+" indicates that the system might be affected.\n\n")
@@ -155,7 +163,7 @@ def summarylist(myglsalist, fd1=sys.stdout, fd2=sys.stderr):
if verbose:
fd2.write(("invalid GLSA: %s (error message was: %s)\n" % (myid, e)))
continue
- if myglsa.isApplied():
+ if myglsa.isInjected():
status = "[A]"
color = white
elif myglsa.isVulnerable():
@@ -186,7 +194,7 @@ def summarylist(myglsalist, fd1=sys.stdout, fd2=sys.stderr):
fd1.write(")")
if list_cve:
fd1.write(" "+(",".join([r[:13] for r in myglsa.references if r[:4] in ["CAN-", "CVE-"]])))
- fd1.write("\n")
+ fd1.write("\n")
return 0
if mode == "list":
@@ -204,39 +212,46 @@ if mode in ["dump", "fix", "inject", "pretend"]:
if mode == "dump":
myglsa.dump()
elif mode == "fix":
- sys.stdout.write("fixing "+myid+"\n")
- mergelist = myglsa.getMergeList(least_change=least_change)
- for pkg in mergelist:
- sys.stdout.write(">>> merging "+pkg+"\n")
- # using emerge for the actual merging as it contains the dependency
- # code and we want to be consistent in behaviour. Also this functionality
- # will be integrated in emerge later, so it shouldn't hurt much.
- emergecmd = "emerge --oneshot " + portage.settings["EMERGE_OPTS"] + " =" + pkg
- if verbose:
- sys.stderr.write(emergecmd+"\n")
- exitcode = os.system(emergecmd)
- # system() returns the exitcode in the high byte of a 16bit integer
- if exitcode >= 1<<8:
- exitcode >>= 8
- if exitcode:
- sys.exit(exitcode)
- myglsa.inject()
+ sys.stdout.write("Fixing GLSA "+myid+"\n")
+ if not myglsa.isVulnerable():
+ sys.stdout.write(">>> no vulnerable packages installed\n")
+ else:
+ mergelist = myglsa.getMergeList(least_change=least_change)
+ if mergelist == []:
+ sys.stdout.write(">>> cannot fix GLSA, no unaffected packages available\n")
+ sys.exit(2)
+ for pkg in mergelist:
+ sys.stdout.write(">>> merging "+pkg+"\n")
+ # using emerge for the actual merging as it contains the dependency
+ # code and we want to be consistent in behaviour. Also this functionality
+ # will be integrated in emerge later, so it shouldn't hurt much.
+ emergecmd = "emerge --oneshot " + " =" + pkg
+ if verbose:
+ sys.stderr.write(emergecmd+"\n")
+ exitcode = os.system(emergecmd)
+ # system() returns the exitcode in the high byte of a 16bit integer
+ if exitcode >= 1<<8:
+ exitcode >>= 8
+ if exitcode:
+ sys.exit(exitcode)
+ if len(mergelist):
+ sys.stdout.write("\n")
elif mode == "pretend":
sys.stdout.write("Checking GLSA "+myid+"\n")
- mergelist = myglsa.getMergeList(least_change=least_change)
- if mergelist:
- sys.stdout.write("The following updates will be performed for this GLSA:\n")
- for pkg in mergelist:
- oldver = None
- for x in vardb.match(portage.cpv_getkey(pkg)):
- if vardb.aux_get(x, ["SLOT"]) == portdb.aux_get(pkg, ["SLOT"]):
- oldver = x
- if oldver == None:
- raise ValueError("could not find old version for package %s" % pkg)
- oldver = oldver[len(portage.cpv_getkey(oldver))+1:]
- sys.stdout.write(" " + pkg + " (" + oldver + ")\n")
+ if not myglsa.isVulnerable():
+ sys.stdout.write(">>> no vulnerable packages installed\n")
else:
- sys.stdout.write("Nothing to do for this GLSA\n")
+ mergedict = {}
+ for (vuln, update) in myglsa.getAffectionTable(least_change=least_change):
+ mergedict.setdefault(update, []).append(vuln)
+
+ sys.stdout.write(">>> The following updates will be performed for this GLSA:\n")
+ for pkg in mergedict:
+ if pkg != "":
+ sys.stdout.write(" " + pkg + " (vulnerable: " + ", ".join(mergedict[pkg]) + ")\n")
+ if "" in mergedict:
+ sys.stdout.write("\n>>> For the following packages, no upgrade path exists:\n")
+ sys.stdout.write(" " + ", ".join(mergedict[""]))
elif mode == "inject":
sys.stdout.write("injecting " + myid + "\n")
myglsa.inject()
@@ -268,9 +283,9 @@ if mode == "test":
# mail mode as requested by solar
if mode == "mail":
import portage.mail, socket
- from io import StringIO
+ from io import BytesIO
from email.mime.text import MIMEText
-
+
# color doesn't make any sense for mail
nocolor()
@@ -278,7 +293,7 @@ if mode == "mail":
myrecipient = portage.settings["PORTAGE_ELOG_MAILURI"].split()[0]
else:
myrecipient = "root@localhost"
-
+
if "PORTAGE_ELOG_MAILFROM" in portage.settings:
myfrom = portage.settings["PORTAGE_ELOG_MAILFROM"]
else:
@@ -287,11 +302,13 @@ if mode == "mail":
mysubject = "[glsa-check] Summary for %s" % socket.getfqdn()
# need a file object for summarylist()
- myfd = StringIO()
- myfd.write("GLSA Summary report for host %s\n" % socket.getfqdn())
- myfd.write("(Command was: %s)\n\n" % " ".join(sys.argv))
+ myfd = BytesIO()
+ line = "GLSA Summary report for host %s\n" % socket.getfqdn()
+ myfd.write(line.encode("utf-8"))
+ line = "(Command was: %s)\n\n" % " ".join(sys.argv)
+ myfd.write(line.encode("utf-8"))
summarylist(glsalist, fd1=myfd, fd2=myfd)
- summary = str(myfd.getvalue())
+ summary = myfd.getvalue().decode("utf-8")
myfd.close()
myattachments = []
@@ -302,16 +319,17 @@ if mode == "mail":
if verbose:
sys.stderr.write(("invalid GLSA: %s (error message was: %s)\n" % (myid, e)))
continue
- myfd = StringIO()
+ myfd = BytesIO()
myglsa.dump(outstream=myfd)
- myattachments.append(MIMEText(str(myfd.getvalue()), _charset="utf8"))
+ attachment = myfd.getvalue().decode("utf-8")
+ myattachments.append(MIMEText(attachment, _charset="utf8"))
myfd.close()
-
+
mymessage = portage.mail.create_message(myfrom, myrecipient, mysubject, summary, myattachments)
portage.mail.send_mail(portage.settings, mymessage)
-
+
sys.exit(0)
-
+
# something wrong here, all valid paths are covered with sys.exit()
sys.stderr.write("nothing more to do\n")
sys.exit(2)