GLSA tool:
- fixed atom matching when slotted packages are found - added info tool, that shows glsa information for the provided identifier - misc bug fixes git-svn-id: http://svn.sabayonlinux.org/projects/entropy/trunk@1164 cd1c1023-2f26-0410-ae45-c471fc1f0318
This commit is contained in:
@@ -1,8 +1,5 @@
|
||||
TODO list:
|
||||
- glsa utility (*)
|
||||
- self.advisories_changed FIXME
|
||||
- tool that prints glsa information
|
||||
- tool that installs all the security updates
|
||||
- improve dependencies order resolution
|
||||
- migrate server code to ServerInterface
|
||||
[] write a tool that helps keeping packages updated (also supporting injected ones)
|
||||
- packages.sabayonlinux.org interactivity (comments + images upload + connection to phpbb user db)
|
||||
|
||||
+6
-1
@@ -43,7 +43,7 @@ def print_help():
|
||||
|
||||
print_info(" \t"+blue("world")+brown("\t\t update system with the latest available packages"))
|
||||
print_info(" \t\t"+red("--ask")+"\t\t\t ask before making any changes")
|
||||
print_info(" \t\t"+red("--fetch")+"\t\t\t just download packages without doing the install")
|
||||
print_info(" \t\t"+red("--fetch")+"\t\t\t just download packages")
|
||||
print_info(" \t\t"+red("--pretend")+"\t\t just show what would be done")
|
||||
print_info(" \t\t"+red("--verbose")+"\t\t show more details about what's going on")
|
||||
print_info(" \t\t"+red("--replay")+"\t\t reinstall all the packages and their dependencies")
|
||||
@@ -58,6 +58,11 @@ def print_help():
|
||||
print_info(" \t\t"+darkgreen("list")+red("\t\t\t list all the available Security Advisories"))
|
||||
print_info(" \t\t\t"+red("--affected")+"\t list only affected")
|
||||
print_info(" \t\t\t"+red("--unaffected")+"\t list only unaffected")
|
||||
print_info(" \t\t"+darkgreen("info")+red("\t\t\t show information about provided advisories identifiers"))
|
||||
print_info(" \t\t"+darkgreen("install")+red("\t\t\t automaticly install all the available security updates"))
|
||||
print_info(" \t\t\t"+red("--ask")+"\t\t\t ask before making any changes")
|
||||
print_info(" \t\t\t"+red("--fetch")+"\t\t\t just download packages")
|
||||
print_info(" \t\t\t"+red("--pretend")+"\t\t just show what would be done")
|
||||
print_info(" \t\t"+red("--quiet")+"\t\t\t show less details (useful for scripting)")
|
||||
|
||||
print_info(" \t"+blue("install")+brown("\t\t install one or more packages or .tbz2"))
|
||||
|
||||
@@ -32,21 +32,141 @@ def security(options):
|
||||
|
||||
only_affected = False
|
||||
only_unaffected = False
|
||||
fetch = False
|
||||
for opt in options:
|
||||
if opt == "--affected":
|
||||
only_affected = True
|
||||
elif opt == "--unaffected":
|
||||
only_unaffected = True
|
||||
elif opt == "--fetch":
|
||||
fetch = True
|
||||
|
||||
if options[0] == "update":
|
||||
rc = Equo.Security.fetch_advisories()
|
||||
elif options[0] == "list":
|
||||
rc = list_advisories(only_affected = only_affected, only_unaffected = only_unaffected)
|
||||
elif options[0] == "install":
|
||||
Equo.load_cache()
|
||||
rc = install_packages(fetch = fetch)
|
||||
Equo.save_cache()
|
||||
elif options[0] == "info":
|
||||
rc = show_advisories_info(options[1:])
|
||||
else:
|
||||
rc = -10
|
||||
|
||||
return rc
|
||||
|
||||
def show_advisories_info(advisories):
|
||||
if not advisories:
|
||||
print_error(brown(" :: ")+darkgreen("No advisories provided."))
|
||||
return 1
|
||||
|
||||
adv_metadata = Equo.Security.get_advisories_metadata()
|
||||
for advisory in advisories:
|
||||
if advisory not in adv_metadata:
|
||||
print_warning(brown(" :: ")+darkred("Advisory ")+blue(advisory)+darkred(" does not exist."))
|
||||
continue
|
||||
print_advisory_information(adv_metadata[advisory], key = advisory)
|
||||
|
||||
return 0
|
||||
|
||||
def print_advisory_information(advisory_data, key):
|
||||
|
||||
# print advisory code
|
||||
glsa_url = "http://www.gentoo.org/security/en/glsa/%s" % (advisory_data['filename'],)
|
||||
print_info(blue(" @@ ")+red("GLSA Identifier ")+bold(key)+red(" | ")+blue(glsa_url))
|
||||
|
||||
# title
|
||||
print_info("\t"+darkgreen("Title:\t\t")+darkred(advisory_data['title']))
|
||||
|
||||
# description
|
||||
description = advisory_data['description'].split("\n")
|
||||
desc_text = "\t"+darkgreen("Description:\t")
|
||||
for x in description:
|
||||
print_info(desc_text+x.strip())
|
||||
desc_text = "\t\t\t"
|
||||
|
||||
# background
|
||||
if advisory_data['background']:
|
||||
background = advisory_data['background'].split("\n")
|
||||
bg_text = "\t"+darkgreen("Background:\t")
|
||||
for x in background:
|
||||
print_info(bg_text+purple(x.strip()))
|
||||
bg_text = "\t\t\t"
|
||||
|
||||
# access
|
||||
if advisory_data['access']:
|
||||
print_info("\t"+darkgreen("Exploitable:\t")+bold(advisory_data['access']))
|
||||
|
||||
# impact
|
||||
if advisory_data['impact']:
|
||||
impact = advisory_data['impact'].split("\n")
|
||||
imp_text = "\t"+darkgreen("Impact:\t\t")
|
||||
for x in impact:
|
||||
print_info(imp_text+brown(x.strip()))
|
||||
imp_text = "\t\t\t"
|
||||
|
||||
# impact type
|
||||
if advisory_data['impacttype']:
|
||||
print_info("\t"+darkgreen("Impact type:\t")+bold(advisory_data['impacttype']))
|
||||
|
||||
# revised
|
||||
if advisory_data['revised']:
|
||||
print_info("\t"+darkgreen("Revised:\t")+brown(advisory_data['revised']))
|
||||
|
||||
# announced
|
||||
if advisory_data['announced']:
|
||||
print_info("\t"+darkgreen("Announced:\t")+brown(advisory_data['announced']))
|
||||
|
||||
# synopsis
|
||||
synopsis = advisory_data['synopsis'].split("\n")
|
||||
syn_text = "\t"+darkgreen("Synopsis:\t")
|
||||
for x in synopsis:
|
||||
print_info(syn_text+x.strip())
|
||||
syn_text = "\t\t\t"
|
||||
|
||||
# references
|
||||
if advisory_data['references']:
|
||||
print_info("\t"+darkgreen("References:"))
|
||||
for reference in advisory_data['references']:
|
||||
print_info("\t\t\t"+darkblue(reference))
|
||||
|
||||
# gentoo bugs
|
||||
if advisory_data['bugs']:
|
||||
print_info("\t"+darkgreen("Gentoo bugs:"))
|
||||
for bug in advisory_data['bugs']:
|
||||
bug = "https://bugs.gentoo.org/show_bug.cgi?id=%s" % (bug,)
|
||||
print_info("\t\t\t"+darkblue(bug))
|
||||
|
||||
# affected
|
||||
if advisory_data['affected']:
|
||||
print_info("\t"+darkgreen("Affected:"))
|
||||
for key in advisory_data['affected']:
|
||||
print_info("\t\t\t"+darkred(key))
|
||||
affected_data = advisory_data['affected'][key][0]
|
||||
vul_vers = affected_data['vul_vers']
|
||||
unaff_vers = affected_data['unaff_vers']
|
||||
if vul_vers:
|
||||
print_info("\t\t\t "+brown("vulnerable versions: ")+", ".join(vul_vers))
|
||||
if unaff_vers:
|
||||
print_info("\t\t\t "+brown("unaffected versions: ")+", ".join(unaff_vers))
|
||||
#print affected_data
|
||||
|
||||
# workaround
|
||||
if advisory_data['workaround']:
|
||||
print_info("\t"+darkgreen("Workaround:\t")+darkred(advisory_data['workaround']))
|
||||
|
||||
# resolution
|
||||
if advisory_data['resolution']:
|
||||
res_text = "\t"+darkgreen("Resolution:\t")
|
||||
resolutions = advisory_data['resolution']
|
||||
for resolution in resolutions:
|
||||
for x in resolution.split("\n"):
|
||||
print_info(res_text+x.strip())
|
||||
res_text = "\t\t\t"
|
||||
|
||||
{'background': u''}
|
||||
|
||||
|
||||
def list_advisories(only_affected = False, only_unaffected = False):
|
||||
if (not only_affected and not only_unaffected) or (only_affected and only_unaffected):
|
||||
@@ -85,4 +205,28 @@ def list_advisories(only_affected = False, only_unaffected = False):
|
||||
print_info(description)
|
||||
return 0
|
||||
|
||||
def install_packages(fetch = False):
|
||||
|
||||
import text_ui
|
||||
|
||||
print_info(red(" @@ ")+blue("Calculating security updates..."))
|
||||
affected_atoms = Equo.Security.get_affected_atoms()
|
||||
# match in client database
|
||||
valid_matches = set()
|
||||
for atom in affected_atoms:
|
||||
match = Equo.clientDbconn.atomMatch(atom)
|
||||
if match[0] == -1:
|
||||
continue
|
||||
# get key + slot
|
||||
key, slot = Equo.clientDbconn.retrieveKeySlot(match[0])
|
||||
# match in repos
|
||||
match = Equo.atomMatch(key, matchSlot = slot)
|
||||
if match[0] != -1:
|
||||
valid_matches.add(match)
|
||||
|
||||
if not valid_matches:
|
||||
print_info(red(" @@ ")+blue("All the available updates have been already installed."))
|
||||
return 0
|
||||
|
||||
rc, stat = text_ui.installPackages(atomsdata = valid_matches, onlyfetch = fetch)
|
||||
return rc
|
||||
|
||||
+49
-23
@@ -4853,10 +4853,8 @@ class TriggerInterface:
|
||||
functions.add('addbootablekernel')
|
||||
if x.startswith('/usr/src/'):
|
||||
functions.add('createkernelsym')
|
||||
'''
|
||||
if x.startswith('/etc/env.d/'):
|
||||
functions.add('env_update')
|
||||
'''
|
||||
if os.path.dirname(x) in ldpaths:
|
||||
if x.find(".so") > -1:
|
||||
functions.add('run_ldconfig')
|
||||
@@ -6215,7 +6213,7 @@ class SecurityInterface:
|
||||
"ge": ">=",
|
||||
"rge": ">=", # >=~
|
||||
"rle": "<=", # <=~
|
||||
"rgt": " >", # >~
|
||||
"rgt": ">", # >~
|
||||
"rlt": "<" # <~
|
||||
}
|
||||
|
||||
@@ -6225,24 +6223,23 @@ class SecurityInterface:
|
||||
self.security_url_checksum = etpConst['securityurl']+etpConst['packageshashfileext']
|
||||
self.download_package = os.path.join(self.unpackdir,os.path.basename(etpConst['securityurl']))
|
||||
self.download_package_checksum = self.download_package+etpConst['packageshashfileext']
|
||||
self.old_download_package_checksum = os.path.join(etpConst['dumpstoragedir'],os.path.basename(etpConst['securityurl']))+etpConst['packageshashfileext']
|
||||
|
||||
self.security_package = os.path.join(etpConst['securitydir'],os.path.basename(etpConst['securityurl']))
|
||||
self.security_package_checksum = self.security_package+etpConst['packageshashfileext']
|
||||
|
||||
|
||||
if os.path.isfile(etpConst['securitydir']) or os.path.islink(etpConst['securitydir']):
|
||||
os.remove(etpConst['securitydir'])
|
||||
if not os.path.isdir(etpConst['securitydir']):
|
||||
os.makedirs(etpConst['securitydir'])
|
||||
elif os.path.isfile(self.security_package_checksum):
|
||||
elif os.path.isfile(self.old_download_package_checksum):
|
||||
f = open(self.old_download_package_checksum)
|
||||
try:
|
||||
f = open(self.security_package_checksum)
|
||||
self.previous_checksum = f.readline().strip().split()[0]
|
||||
f.close()
|
||||
except: # FIXME really horrible exception trapping
|
||||
try:
|
||||
f.close()
|
||||
except:
|
||||
pass
|
||||
except:
|
||||
pass
|
||||
f.close()
|
||||
|
||||
def __prepare_unpack(self):
|
||||
|
||||
@@ -6457,12 +6454,15 @@ class SecurityInterface:
|
||||
vul_atoms = mydata['affected'][key][0]['vul_atoms']
|
||||
unaff_atoms = mydata['affected'][key][0]['unaff_atoms']
|
||||
unaffected_atoms = set()
|
||||
for atom in unaff_atoms:
|
||||
match = self.Entropy.clientDbconn.atomMatch(atom)
|
||||
if match[0] != -1:
|
||||
unaffected_atoms.add(match)
|
||||
if not vul_atoms:
|
||||
return False
|
||||
# XXX: does multimatch work correctly?
|
||||
for atom in unaff_atoms:
|
||||
matches = self.Entropy.clientDbconn.atomMatch(atom, multiMatch = True)
|
||||
if matches[1] == 0:
|
||||
for idpackage in matches[0]:
|
||||
unaffected_atoms.add((idpackage,0))
|
||||
|
||||
for atom in vul_atoms:
|
||||
match = self.Entropy.clientDbconn.atomMatch(atom)
|
||||
if (match[0] != -1) and (match not in unaffected_atoms):
|
||||
@@ -6555,16 +6555,38 @@ class SecurityInterface:
|
||||
references = glsa_tree.getElementsByTagName("references")[0]
|
||||
xml_data['references'] = [x.getAttribute("link").strip() for x in references.getElementsByTagName("uri")]
|
||||
|
||||
xml_data['description'] = glsa_tree.getElementsByTagName("description")[0].firstChild.data.strip()
|
||||
xml_data['workaround'] = glsa_tree.getElementsByTagName("workaround")[0].firstChild.data.strip()
|
||||
xml_data['resolution'] = glsa_tree.getElementsByTagName("resolution")[0].firstChild.data.strip()
|
||||
xml_data['impact'] = glsa_tree.getElementsByTagName("impact")[0].firstChild.data.strip()
|
||||
xml_data['impacttype'] = glsa_tree.getElementsByTagName("impact")[0].getAttribute("type").strip()
|
||||
xml_data['background'] = ""
|
||||
try:
|
||||
xml_data['background'] = glsa_tree.getElementsByTagName("background")[0].firstChild.data.strip()
|
||||
description = glsa_tree.getElementsByTagName("description")[0]
|
||||
xml_data['description'] = description.getElementsByTagName("p")[0].firstChild.data.strip()
|
||||
except IndexError:
|
||||
pass
|
||||
xml_data['description'] = ""
|
||||
try:
|
||||
workaround = glsa_tree.getElementsByTagName("workaround")[0]
|
||||
xml_data['workaround'] = workaround.getElementsByTagName("p")[0].firstChild.data.strip()
|
||||
except IndexError:
|
||||
xml_data['workaround'] = ""
|
||||
|
||||
try:
|
||||
xml_data['resolution'] = []
|
||||
resolution = glsa_tree.getElementsByTagName("resolution")[0]
|
||||
p_elements = resolution.getElementsByTagName("p")
|
||||
for p_elem in p_elements:
|
||||
xml_data['resolution'].append(p_elem.firstChild.data.strip())
|
||||
except IndexError:
|
||||
xml_data['resolution'] = []
|
||||
|
||||
try:
|
||||
impact = glsa_tree.getElementsByTagName("impact")[0]
|
||||
xml_data['impact'] = impact.getElementsByTagName("p")[0].firstChild.data.strip()
|
||||
except IndexError:
|
||||
xml_data['impact'] = ""
|
||||
xml_data['impacttype'] = glsa_tree.getElementsByTagName("impact")[0].getAttribute("type").strip()
|
||||
|
||||
try:
|
||||
background = glsa_tree.getElementsByTagName("background")[0]
|
||||
xml_data['background'] = background.getElementsByTagName("p")[0].firstChild.data.strip()
|
||||
except IndexError:
|
||||
xml_data['background'] = ""
|
||||
|
||||
# affection information
|
||||
affected = glsa_tree.getElementsByTagName("affected")[0]
|
||||
@@ -6720,6 +6742,10 @@ class SecurityInterface:
|
||||
else:
|
||||
raise exceptionTools.InvalidData("InvalidData: return status not valid.")
|
||||
|
||||
# save downloaded md5
|
||||
if os.path.isfile(self.download_package_checksum) and os.path.isdir(etpConst['dumpstoragedir']):
|
||||
shutil.copy2(self.download_package_checksum,self.old_download_package_checksum)
|
||||
|
||||
# now unpack in place
|
||||
status = self.__unpack_advisories()
|
||||
if status != 0:
|
||||
|
||||
Reference in New Issue
Block a user