entropy.security: initial code review and cleanup
This commit is contained in:
+231
-124
@@ -22,7 +22,7 @@
|
||||
|
||||
import os
|
||||
import shutil
|
||||
from entropy.exceptions import *
|
||||
from entropy.exceptions import IncorrectParameter, InvalidData
|
||||
from entropy.const import etpConst, etpCache, etpUi, const_setup_perms
|
||||
from entropy.i18n import _
|
||||
from entropy.output import blue, bold, red, darkgreen, darkred
|
||||
@@ -38,12 +38,14 @@ class SecurityInterface:
|
||||
# This program is licensed under the GPL, version 2
|
||||
|
||||
# WARNING: this code is only tested by a few people and should NOT be used
|
||||
# on production systems at this stage. There are possible security holes and probably
|
||||
# on production systems at this stage.
|
||||
# There are possible security holes and probably
|
||||
# bugs in this code. If you test it please report ANY success or failure to
|
||||
# me (genone@gentoo.org).
|
||||
|
||||
# The following planned features are currently on hold:
|
||||
# - getting GLSAs from http/ftp servers (not really useful without the fixed ebuilds)
|
||||
# - getting GLSAs from http/ftp servers
|
||||
# (not really useful without the fixed ebuilds)
|
||||
# - GPG signing/verification (until key policy is clear)
|
||||
|
||||
import entropy.tools as entropyTools
|
||||
@@ -51,13 +53,13 @@ class SecurityInterface:
|
||||
|
||||
# disabled for now
|
||||
from entropy.client.interfaces import Client
|
||||
if not isinstance(EquoInstance,Client):
|
||||
if not isinstance(EquoInstance, Client):
|
||||
mytxt = _("A valid Client interface instance is needed")
|
||||
raise IncorrectParameter("IncorrectParameter: %s" % (mytxt,))
|
||||
|
||||
self.Entropy = EquoInstance
|
||||
from entropy.cache import EntropyCacher
|
||||
self.Cacher = EntropyCacher()
|
||||
self.__cacher = EntropyCacher()
|
||||
from entropy.core import SystemSettings
|
||||
self.SystemSettings = SystemSettings()
|
||||
self.lastfetch = None
|
||||
@@ -70,71 +72,88 @@ class SecurityInterface:
|
||||
self.minidom = minidom
|
||||
|
||||
self.op_mappings = {
|
||||
"le": "<=",
|
||||
"lt": "<",
|
||||
"eq": "=",
|
||||
"gt": ">",
|
||||
"ge": ">=",
|
||||
"rge": ">=", # >=~
|
||||
"rle": "<=", # <=~
|
||||
"rgt": ">", # >~
|
||||
"rlt": "<" # <~
|
||||
"le": "<=",
|
||||
"lt": "<",
|
||||
"eq": "=",
|
||||
"gt": ">",
|
||||
"ge": ">=",
|
||||
"rge": ">=", # >=~
|
||||
"rle": "<=", # <=~
|
||||
"rgt": ">", # >~
|
||||
"rlt": "<" # <~
|
||||
}
|
||||
|
||||
security_url = self.SystemSettings['repositories']['security_advisories_url']
|
||||
self.unpackdir = os.path.join(etpConst['entropyunpackdir'],"security-"+str(self.entropyTools.get_random_number()))
|
||||
self.security_url = security_url
|
||||
self.unpacked_package = os.path.join(self.unpackdir,"glsa_package")
|
||||
self.security_url_checksum = security_url+etpConst['packagesmd5fileext']
|
||||
self.download_package = os.path.join(self.unpackdir,os.path.basename(security_url))
|
||||
self.download_package_checksum = self.download_package+etpConst['packagesmd5fileext']
|
||||
self.old_download_package_checksum = os.path.join(etpConst['dumpstoragedir'],os.path.basename(security_url))+etpConst['packagesmd5fileext']
|
||||
security_url = \
|
||||
self.SystemSettings['repositories']['security_advisories_url']
|
||||
security_file = os.path.basename(security_url)
|
||||
md5_ext = etpConst['packagesmd5fileext']
|
||||
|
||||
self.security_package = os.path.join(etpConst['securitydir'],os.path.basename(security_url))
|
||||
self.security_package_checksum = self.security_package+etpConst['packagesmd5fileext']
|
||||
self.unpackdir = os.path.join(etpConst['entropyunpackdir'],
|
||||
"security-%s" % (self.entropyTools.get_random_number(),))
|
||||
self.security_url = security_url
|
||||
self.unpacked_package = os.path.join(self.unpackdir, "glsa_package")
|
||||
self.security_url_checksum = security_url + md5_ext
|
||||
|
||||
self.download_package = os.path.join(self.unpackdir, security_file)
|
||||
self.download_package_checksum = self.download_package + md5_ext
|
||||
self.old_download_package_checksum = os.path.join(
|
||||
etpConst['dumpstoragedir'], os.path.basename(security_url)
|
||||
) + md5_ext
|
||||
|
||||
self.security_package = os.path.join(etpConst['securitydir'],
|
||||
os.path.basename(security_url))
|
||||
self.security_package_checksum = self.security_package + md5_ext
|
||||
|
||||
try:
|
||||
if os.path.isfile(etpConst['securitydir']) or os.path.islink(etpConst['securitydir']):
|
||||
|
||||
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'],0775)
|
||||
os.makedirs(etpConst['securitydir'], 0775)
|
||||
|
||||
except OSError:
|
||||
pass
|
||||
const_setup_perms(etpConst['securitydir'],etpConst['entropygid'])
|
||||
const_setup_perms(etpConst['securitydir'], etpConst['entropygid'])
|
||||
|
||||
if os.path.isfile(self.old_download_package_checksum):
|
||||
f = open(self.old_download_package_checksum)
|
||||
if os.access(self.old_download_package_checksum, os.F_OK | os.R_OK):
|
||||
f_down = open(self.old_download_package_checksum)
|
||||
try:
|
||||
self.previous_checksum = f.readline().strip().split()[0]
|
||||
except:
|
||||
self.previous_checksum = f_down.readline().strip().split()[0]
|
||||
except (IndexError, OSError, IOError,):
|
||||
pass
|
||||
f.close()
|
||||
f_down.close()
|
||||
|
||||
def __prepare_unpack(self):
|
||||
|
||||
if os.path.isfile(self.unpackdir) or os.path.islink(self.unpackdir):
|
||||
os.remove(self.unpackdir)
|
||||
|
||||
if os.path.isdir(self.unpackdir):
|
||||
shutil.rmtree(self.unpackdir,True)
|
||||
shutil.rmtree(self.unpackdir, True)
|
||||
try:
|
||||
os.rmdir(self.unpackdir)
|
||||
except OSError:
|
||||
pass
|
||||
os.makedirs(self.unpackdir,0775)
|
||||
const_setup_perms(self.unpackdir,etpConst['entropygid'])
|
||||
|
||||
os.makedirs(self.unpackdir, 0775)
|
||||
const_setup_perms(self.unpackdir, etpConst['entropygid'])
|
||||
|
||||
def __download_glsa_package(self):
|
||||
return self.__generic_download(self.security_url, self.download_package)
|
||||
|
||||
def __download_glsa_package_checksum(self):
|
||||
return self.__generic_download(self.security_url_checksum, self.download_package_checksum, show_speed = False)
|
||||
def __download_glsa_package_cksum(self):
|
||||
return self.__generic_download(self.security_url_checksum,
|
||||
self.download_package_checksum, show_speed = False)
|
||||
|
||||
def __generic_download(self, url, save_to, show_speed = True):
|
||||
fetchConn = self.Entropy.urlFetcher(url, save_to, resume = False, show_speed = show_speed)
|
||||
fetchConn.progress = self.Entropy.progress
|
||||
rc = fetchConn.download()
|
||||
del fetchConn
|
||||
if rc in ("-1","-2","-3","-4"):
|
||||
fetcher = self.Entropy.urlFetcher(url, save_to, resume = False,
|
||||
show_speed = show_speed)
|
||||
fetcher.progress = self.Entropy.progress
|
||||
rc_fetch = fetcher.download()
|
||||
del fetcher
|
||||
if rc_fetch in ("-1", "-2", "-3", "-4"):
|
||||
return False
|
||||
# setup permissions
|
||||
self.Entropy.setup_default_file_perms(save_to)
|
||||
@@ -143,21 +162,22 @@ class SecurityInterface:
|
||||
def __verify_checksum(self):
|
||||
|
||||
# read checksum
|
||||
if not os.path.isfile(self.download_package_checksum) or not os.access(self.download_package_checksum,os.R_OK):
|
||||
if not os.path.isfile(self.download_package_checksum) or \
|
||||
not os.access(self.download_package_checksum, os.R_OK):
|
||||
return 1
|
||||
|
||||
f = open(self.download_package_checksum)
|
||||
try:
|
||||
checksum = f.readline().strip().split()[0]
|
||||
f.close()
|
||||
except:
|
||||
except (OSError, IOError, IndexError,):
|
||||
return 2
|
||||
|
||||
if checksum == self.previous_checksum:
|
||||
self.advisories_changed = False
|
||||
else:
|
||||
self.advisories_changed = True
|
||||
md5res = self.entropyTools.compare_md5(self.download_package,checksum)
|
||||
md5res = self.entropyTools.compare_md5(self.download_package, checksum)
|
||||
if not md5res:
|
||||
return 3
|
||||
return 0
|
||||
@@ -168,24 +188,24 @@ class SecurityInterface:
|
||||
self.unpacked_package,
|
||||
catchEmpty = True
|
||||
)
|
||||
const_setup_perms(self.unpacked_package,etpConst['entropygid'])
|
||||
const_setup_perms(self.unpacked_package, etpConst['entropygid'])
|
||||
return rc
|
||||
|
||||
def __clear_previous_advisories(self):
|
||||
if os.listdir(etpConst['securitydir']):
|
||||
shutil.rmtree(etpConst['securitydir'],True)
|
||||
shutil.rmtree(etpConst['securitydir'], True)
|
||||
if not os.path.isdir(etpConst['securitydir']):
|
||||
os.makedirs(etpConst['securitydir'],0775)
|
||||
const_setup_perms(self.unpackdir,etpConst['entropygid'])
|
||||
os.makedirs(etpConst['securitydir'], 0775)
|
||||
const_setup_perms(self.unpackdir, etpConst['entropygid'])
|
||||
|
||||
def __put_advisories_in_place(self):
|
||||
for advfile in os.listdir(self.unpacked_package):
|
||||
from_file = os.path.join(self.unpacked_package,advfile)
|
||||
to_file = os.path.join(etpConst['securitydir'],advfile)
|
||||
shutil.move(from_file,to_file)
|
||||
from_file = os.path.join(self.unpacked_package, advfile)
|
||||
to_file = os.path.join(etpConst['securitydir'], advfile)
|
||||
shutil.move(from_file, to_file)
|
||||
|
||||
def __cleanup_garbage(self):
|
||||
shutil.rmtree(self.unpackdir,True)
|
||||
shutil.rmtree(self.unpackdir, True)
|
||||
|
||||
def clear(self, xcache = False):
|
||||
self.adv_metadata = None
|
||||
@@ -198,28 +218,39 @@ class SecurityInterface:
|
||||
return self.adv_metadata
|
||||
|
||||
if self.Entropy.xcache:
|
||||
dir_checksum = self.entropyTools.md5sum_directory(etpConst['securitydir'])
|
||||
c_hash = "%s%s" % (etpCache['advisories'],hash("%s|%s|%s" % (
|
||||
hash(self.SystemSettings['repositories']['branch']), hash(dir_checksum),
|
||||
hash(etpConst['systemroot']),)),)
|
||||
adv_metadata = self.Cacher.pop(c_hash)
|
||||
dir_checksum = self.entropyTools.md5sum_directory(
|
||||
etpConst['securitydir'])
|
||||
c_hash = "%s%s" % (
|
||||
etpCache['advisories'], hash("%s|%s|%s" % (
|
||||
hash(self.SystemSettings['repositories']['branch']),
|
||||
hash(dir_checksum),
|
||||
hash(etpConst['systemroot']),
|
||||
)),
|
||||
)
|
||||
adv_metadata = self.__cacher.pop(c_hash)
|
||||
if adv_metadata != None:
|
||||
self.adv_metadata = adv_metadata.copy()
|
||||
return self.adv_metadata
|
||||
|
||||
def set_advisories_cache(self, adv_metadata):
|
||||
if self.Entropy.xcache:
|
||||
dir_checksum = self.entropyTools.md5sum_directory(etpConst['securitydir'])
|
||||
c_hash = "%s%s" % (etpCache['advisories'],hash("%s|%s|%s" % (
|
||||
hash(self.SystemSettings['repositories']['branch']), hash(dir_checksum),
|
||||
hash(etpConst['systemroot']),)),)
|
||||
self.Cacher.push(c_hash,adv_metadata)
|
||||
dir_checksum = self.entropyTools.md5sum_directory(
|
||||
etpConst['securitydir'])
|
||||
c_hash = "%s%s" % (
|
||||
etpCache['advisories'], hash("%s|%s|%s" % (
|
||||
hash(self.SystemSettings['repositories']['branch']),
|
||||
hash(dir_checksum),
|
||||
hash(etpConst['systemroot']),
|
||||
)),
|
||||
)
|
||||
self.__cacher.push(c_hash, adv_metadata)
|
||||
|
||||
def get_advisories_list(self):
|
||||
if not self.check_advisories_availability():
|
||||
return []
|
||||
xmls = os.listdir(etpConst['securitydir'])
|
||||
xmls = sorted([x for x in xmls if x.endswith(".xml") and x.startswith("glsa-")])
|
||||
xmls = sorted([x for x in xmls if x.endswith(".xml") and \
|
||||
x.startswith("glsa-")])
|
||||
return xmls
|
||||
|
||||
def get_advisories_metadata(self):
|
||||
@@ -235,7 +266,10 @@ class SecurityInterface:
|
||||
for xml in xmls:
|
||||
|
||||
count += 1
|
||||
if not etpUi['quiet']: self.Entropy.updateProgress(":: "+str(round((float(count)/maxlen)*100,1))+"% ::", importance = 0, type = "info", back = True)
|
||||
if not etpUi['quiet']:
|
||||
self.Entropy.updateProgress(":: " + \
|
||||
str(round((float(count)/maxlen)*100,1)) + "% ::",
|
||||
importance = 0, type = "info", back = True)
|
||||
|
||||
xml_metadata = None
|
||||
exc_string = ""
|
||||
@@ -244,14 +278,14 @@ class SecurityInterface:
|
||||
xml_metadata = self.get_xml_metadata(xml)
|
||||
except KeyboardInterrupt:
|
||||
return {}
|
||||
except Exception, e:
|
||||
exc_string = str(Exception)
|
||||
exc_err = str(e)
|
||||
except Exception, err:
|
||||
exc_string = unicode(Exception)
|
||||
exc_err = unicode(err)
|
||||
if xml_metadata == None:
|
||||
more_info = ""
|
||||
if exc_string:
|
||||
mytxt = _("Error")
|
||||
more_info = " %s: %s: %s" % (mytxt,exc_string,exc_err,)
|
||||
more_info = " %s: %s: %s" % (mytxt, exc_string, exc_err,)
|
||||
mytxt = "%s: %s: %s! %s" % (
|
||||
blue(_("Warning")),
|
||||
bold(xml),
|
||||
@@ -307,7 +341,7 @@ class SecurityInterface:
|
||||
|
||||
return adv_metadata
|
||||
|
||||
def is_affected(self, adv_key, adv_data = {}):
|
||||
def is_affected(self, adv_key, adv_data = None):
|
||||
if not adv_data:
|
||||
adv_data = self.get_advisories_metadata()
|
||||
if adv_key not in adv_data:
|
||||
@@ -326,9 +360,10 @@ class SecurityInterface:
|
||||
if not vul_atoms:
|
||||
return False
|
||||
for atom in unaff_atoms:
|
||||
matches = self.Entropy.clientDbconn.atomMatch(atom, multiMatch = True)
|
||||
matches = self.Entropy.clientDbconn.atomMatch(atom,
|
||||
multiMatch = True)
|
||||
for idpackage in matches[0]:
|
||||
unaffected_atoms.add((idpackage,0))
|
||||
unaffected_atoms.add((idpackage, 0))
|
||||
|
||||
for atom in vul_atoms:
|
||||
match = self.Entropy.clientDbconn.atomMatch(atom)
|
||||
@@ -352,7 +387,7 @@ class SecurityInterface:
|
||||
adv_data_keys = adv_data.keys()
|
||||
valid_keys = set()
|
||||
for adv in adv_data_keys:
|
||||
is_affected = self.is_affected(adv,adv_data)
|
||||
is_affected = self.is_affected(adv, adv_data)
|
||||
if affected == is_affected:
|
||||
valid_keys.add(adv)
|
||||
# we need to filter our adv_data and return
|
||||
@@ -385,8 +420,9 @@ class SecurityInterface:
|
||||
return self.affected_atoms
|
||||
|
||||
def get_xml_metadata(self, xmlfilename):
|
||||
|
||||
xml_data = {}
|
||||
xmlfile = os.path.join(etpConst['securitydir'],xmlfilename)
|
||||
xmlfile = os.path.join(etpConst['securitydir'], xmlfilename)
|
||||
try:
|
||||
xmldoc = self.minidom.parse(xmlfile)
|
||||
except:
|
||||
@@ -399,44 +435,58 @@ class SecurityInterface:
|
||||
return {}
|
||||
|
||||
glsa_id = glsa_tree.getAttribute("id")
|
||||
glsa_title = glsa_tree.getElementsByTagName("title")[0].firstChild.data
|
||||
glsa_synopsis = glsa_tree.getElementsByTagName("synopsis")[0].firstChild.data
|
||||
glsa_announced = glsa_tree.getElementsByTagName("announced")[0].firstChild.data
|
||||
glsa_revised = glsa_tree.getElementsByTagName("revised")[0].firstChild.data
|
||||
glsa_title = glsa_tree.getElementsByTagName("title")[0]
|
||||
glsa_title = glsa_title.firstChild.data
|
||||
glsa_synopsis = glsa_tree.getElementsByTagName("synopsis")[0]
|
||||
glsa_synopsis = glsa_synopsis.firstChild.data
|
||||
glsa_announced = glsa_tree.getElementsByTagName("announced")[0]
|
||||
glsa_announced = glsa_announced.firstChild.data
|
||||
glsa_revised = glsa_tree.getElementsByTagName("revised")[0]
|
||||
glsa_revised = glsa_revised.firstChild.data
|
||||
|
||||
xml_data['filename'] = xmlfilename
|
||||
xml_data['url'] = "http://www.gentoo.org/security/en/glsa/%s" % (xmlfilename,)
|
||||
xml_data['url'] = "http://www.gentoo.org/security/en/glsa/%s" % (
|
||||
xmlfilename,)
|
||||
xml_data['title'] = glsa_title.strip()
|
||||
xml_data['synopsis'] = glsa_synopsis.strip()
|
||||
xml_data['announced'] = glsa_announced.strip()
|
||||
xml_data['revised'] = glsa_revised.strip()
|
||||
xml_data['bugs'] = ["https://bugs.gentoo.org/show_bug.cgi?id="+x.firstChild.data.strip() for x in glsa_tree.getElementsByTagName("bug")]
|
||||
xml_data['access'] = ""
|
||||
xml_data['bugs'] = ["https://bugs.gentoo.org/" + \
|
||||
x.firstChild.data.strip() for x in \
|
||||
glsa_tree.getElementsByTagName("bug")]
|
||||
|
||||
try:
|
||||
xml_data['access'] = glsa_tree.getElementsByTagName("access")[0].firstChild.data.strip()
|
||||
glsa_access = glsa_tree.getElementsByTagName("access")[0]
|
||||
xml_data['access'] = glsa_access.firstChild.data.strip()
|
||||
except IndexError:
|
||||
pass
|
||||
xml_data['access'] = ""
|
||||
|
||||
# references
|
||||
references = glsa_tree.getElementsByTagName("references")[0]
|
||||
xml_data['references'] = [x.getAttribute("link").strip() for x in references.getElementsByTagName("uri")]
|
||||
xml_data['references'] = [x.getAttribute("link").strip() for x in \
|
||||
references.getElementsByTagName("uri")]
|
||||
|
||||
try:
|
||||
xml_data['description'] = ""
|
||||
xml_data['description_items'] = []
|
||||
desc = glsa_tree.getElementsByTagName("description")[0].getElementsByTagName("p")[0].firstChild.data.strip()
|
||||
desc = glsa_tree.getElementsByTagName("description")[0]
|
||||
desc = desc.getElementsByTagName("p")[0].firstChild.data.strip()
|
||||
xml_data['description'] = desc
|
||||
items = glsa_tree.getElementsByTagName("description")[0].getElementsByTagName("ul")
|
||||
for item in items:
|
||||
items = glsa_tree.getElementsByTagName("description")[0]
|
||||
for item in items.getElementsByTagName("ul"):
|
||||
li_items = item.getElementsByTagName("li")
|
||||
for li_item in li_items:
|
||||
xml_data['description_items'].append(' '.join([x.strip() for x in li_item.firstChild.data.strip().split("\n")]))
|
||||
xml_data['description_items'].append(' '.join(
|
||||
[x.strip() for x in \
|
||||
li_item.firstChild.data.strip().split("\n")])
|
||||
)
|
||||
except IndexError:
|
||||
xml_data['description'] = ""
|
||||
xml_data['description_items'] = []
|
||||
|
||||
try:
|
||||
workaround = glsa_tree.getElementsByTagName("workaround")[0]
|
||||
xml_data['workaround'] = workaround.getElementsByTagName("p")[0].firstChild.data.strip()
|
||||
workaround_p = workaround.getElementsByTagName("p")[0]
|
||||
xml_data['workaround'] = workaround_p.firstChild.data.strip()
|
||||
except IndexError:
|
||||
xml_data['workaround'] = ""
|
||||
|
||||
@@ -451,14 +501,17 @@ class SecurityInterface:
|
||||
|
||||
try:
|
||||
impact = glsa_tree.getElementsByTagName("impact")[0]
|
||||
xml_data['impact'] = impact.getElementsByTagName("p")[0].firstChild.data.strip()
|
||||
impact_p = impact.getElementsByTagName("p")[0]
|
||||
xml_data['impact'] = impact_p.firstChild.data.strip()
|
||||
except IndexError:
|
||||
xml_data['impact'] = ""
|
||||
xml_data['impacttype'] = glsa_tree.getElementsByTagName("impact")[0].getAttribute("type").strip()
|
||||
impact_type = glsa_tree.getElementsByTagName("impact")[0]
|
||||
xml_data['impacttype'] = impact_type.getAttribute("type").strip()
|
||||
|
||||
try:
|
||||
background = glsa_tree.getElementsByTagName("background")[0]
|
||||
xml_data['background'] = background.getElementsByTagName("p")[0].firstChild.data.strip()
|
||||
background_p = background.getElementsByTagName("p")[0]
|
||||
xml_data['background'] = background_p.firstChild.data.strip()
|
||||
except IndexError:
|
||||
xml_data['background'] = ""
|
||||
|
||||
@@ -467,18 +520,22 @@ class SecurityInterface:
|
||||
affected_packages = {}
|
||||
# we will then filter affected_packages using repositories information
|
||||
# if not affected_packages: advisory will be dropped
|
||||
for p in affected.getElementsByTagName("package"):
|
||||
name = p.getAttribute("name")
|
||||
for pkg in affected.getElementsByTagName("package"):
|
||||
name = pkg.getAttribute("name")
|
||||
if not affected_packages.has_key(name):
|
||||
affected_packages[name] = []
|
||||
|
||||
pdata = {}
|
||||
pdata["arch"] = p.getAttribute("arch").strip()
|
||||
pdata["auto"] = (p.getAttribute("auto") == "yes")
|
||||
pdata["vul_vers"] = [self.__make_version(v) for v in p.getElementsByTagName("vulnerable")]
|
||||
pdata["unaff_vers"] = [self.__make_version(v) for v in p.getElementsByTagName("unaffected")]
|
||||
pdata["vul_atoms"] = [self.__make_atom(name, v) for v in p.getElementsByTagName("vulnerable")]
|
||||
pdata["unaff_atoms"] = [self.__make_atom(name, v) for v in p.getElementsByTagName("unaffected")]
|
||||
pdata["arch"] = pkg.getAttribute("arch").strip()
|
||||
pdata["auto"] = (pkg.getAttribute("auto") == "yes")
|
||||
pdata["vul_vers"] = [self.__make_version(v) for v in \
|
||||
pkg.getElementsByTagName("vulnerable")]
|
||||
pdata["unaff_vers"] = [self.__make_version(v) for v in \
|
||||
pkg.getElementsByTagName("unaffected")]
|
||||
pdata["vul_atoms"] = [self.__make_atom(name, v) for v \
|
||||
in pkg.getElementsByTagName("vulnerable")]
|
||||
pdata["unaff_atoms"] = [self.__make_atom(name, v) for v \
|
||||
in pkg.getElementsByTagName("unaffected")]
|
||||
affected_packages[name].append(pdata)
|
||||
xml_data['affected'] = affected_packages.copy()
|
||||
|
||||
@@ -491,11 +548,12 @@ class SecurityInterface:
|
||||
|
||||
@type vnode: xml.dom.Node
|
||||
@param vnode: a <vulnerable> or <unaffected> Node that
|
||||
contains the version information for this atom
|
||||
contains the version information for this atom
|
||||
@rtype: String
|
||||
@return: the version string
|
||||
"""
|
||||
return self.op_mappings[vnode.getAttribute("range")] + vnode.firstChild.data.strip()
|
||||
return self.op_mappings[vnode.getAttribute("range")] + \
|
||||
vnode.firstChild.data.strip()
|
||||
|
||||
def __make_atom(self, pkgname, vnode):
|
||||
"""
|
||||
@@ -506,11 +564,12 @@ class SecurityInterface:
|
||||
@param pkgname: the name of the package for this atom
|
||||
@type vnode: xml.dom.Node
|
||||
@param vnode: a <vulnerable> or <unaffected> Node that
|
||||
contains the version information for this atom
|
||||
contains the version information for this atom
|
||||
@rtype: String
|
||||
@return: the portage atom
|
||||
"""
|
||||
return str(self.op_mappings[vnode.getAttribute("range")] + pkgname + "-" + vnode.firstChild.data.strip())
|
||||
return str(self.op_mappings[vnode.getAttribute("range")] + pkgname + \
|
||||
"-" + vnode.firstChild.data.strip())
|
||||
|
||||
def check_advisories_availability(self):
|
||||
if not os.path.lexists(etpConst['securitydir']):
|
||||
@@ -523,7 +582,10 @@ class SecurityInterface:
|
||||
|
||||
def fetch_advisories(self, do_cache = True):
|
||||
|
||||
mytxt = "%s: %s" % (bold(_("Security Advisories")),blue(_("testing service connection")),)
|
||||
mytxt = "%s: %s" % (
|
||||
bold(_("Security Advisories")),
|
||||
blue(_("testing service connection")),
|
||||
)
|
||||
self.Entropy.updateProgress(
|
||||
mytxt,
|
||||
importance = 2,
|
||||
@@ -532,7 +594,11 @@ class SecurityInterface:
|
||||
footer = red(" ...")
|
||||
)
|
||||
|
||||
mytxt = "%s: %s %s" % (bold(_("Security Advisories")),blue(_("getting latest GLSAs")),red("..."),)
|
||||
mytxt = "%s: %s %s" % (
|
||||
bold(_("Security Advisories")),
|
||||
blue(_("getting latest GLSAs")),
|
||||
red("..."),
|
||||
)
|
||||
self.Entropy.updateProgress(
|
||||
mytxt,
|
||||
importance = 2,
|
||||
@@ -540,7 +606,8 @@ class SecurityInterface:
|
||||
header = red(" @@ ")
|
||||
)
|
||||
|
||||
gave_up = self.Entropy.lock_check(self.Entropy._resources_run_check_lock)
|
||||
gave_up = self.Entropy.lock_check(
|
||||
self.Entropy._resources_run_check_lock)
|
||||
if gave_up:
|
||||
return 7
|
||||
|
||||
@@ -556,14 +623,21 @@ class SecurityInterface:
|
||||
except:
|
||||
self.Entropy._resources_run_remove_lock()
|
||||
raise
|
||||
if rc != 0: return rc
|
||||
if rc != 0:
|
||||
return rc
|
||||
|
||||
self.Entropy._resources_run_remove_lock()
|
||||
|
||||
if self.advisories_changed:
|
||||
advtext = "%s: %s" % (bold(_("Security Advisories")),darkgreen(_("updated successfully")),)
|
||||
advtext = "%s: %s" % (
|
||||
bold(_("Security Advisories")),
|
||||
darkgreen(_("updated successfully")),
|
||||
)
|
||||
else:
|
||||
advtext = "%s: %s" % (bold(_("Security Advisories")),darkgreen(_("already up to date")),)
|
||||
advtext = "%s: %s" % (
|
||||
bold(_("Security Advisories")),
|
||||
darkgreen(_("already up to date")),
|
||||
)
|
||||
|
||||
if do_cache and self.Entropy.xcache:
|
||||
self.get_advisories_metadata()
|
||||
@@ -584,7 +658,10 @@ class SecurityInterface:
|
||||
status = self.__download_glsa_package()
|
||||
self.lastfetch = status
|
||||
if not status:
|
||||
mytxt = "%s: %s." % (bold(_("Security Advisories")),darkred(_("unable to download the package, sorry")),)
|
||||
mytxt = "%s: %s." % (
|
||||
bold(_("Security Advisories")),
|
||||
darkred(_("unable to download the package, sorry")),
|
||||
)
|
||||
self.Entropy.updateProgress(
|
||||
mytxt,
|
||||
importance = 2,
|
||||
@@ -594,7 +671,11 @@ class SecurityInterface:
|
||||
self.Entropy._resources_run_remove_lock()
|
||||
return 1
|
||||
|
||||
mytxt = "%s: %s %s" % (bold(_("Security Advisories")),blue(_("Verifying checksum")),red("..."),)
|
||||
mytxt = "%s: %s %s" % (
|
||||
bold(_("Security Advisories")),
|
||||
blue(_("Verifying checksum")),
|
||||
red("..."),
|
||||
)
|
||||
self.Entropy.updateProgress(
|
||||
mytxt,
|
||||
importance = 1,
|
||||
@@ -604,9 +685,12 @@ class SecurityInterface:
|
||||
)
|
||||
|
||||
# download digest
|
||||
status = self.__download_glsa_package_checksum()
|
||||
status = self.__download_glsa_package_cksum()
|
||||
if not status:
|
||||
mytxt = "%s: %s." % (bold(_("Security Advisories")),darkred(_("cannot download the checksum, sorry")),)
|
||||
mytxt = "%s: %s." % (
|
||||
bold(_("Security Advisories")),
|
||||
darkred(_("cannot download the checksum, sorry")),
|
||||
)
|
||||
self.Entropy.updateProgress(
|
||||
mytxt,
|
||||
importance = 2,
|
||||
@@ -620,7 +704,10 @@ class SecurityInterface:
|
||||
status = self.__verify_checksum()
|
||||
|
||||
if status == 1:
|
||||
mytxt = "%s: %s." % (bold(_("Security Advisories")),darkred(_("cannot open packages, sorry")),)
|
||||
mytxt = "%s: %s." % (
|
||||
bold(_("Security Advisories")),
|
||||
darkred(_("cannot open packages, sorry")),
|
||||
)
|
||||
self.Entropy.updateProgress(
|
||||
mytxt,
|
||||
importance = 2,
|
||||
@@ -630,7 +717,10 @@ class SecurityInterface:
|
||||
self.Entropy._resources_run_remove_lock()
|
||||
return 3
|
||||
elif status == 2:
|
||||
mytxt = "%s: %s." % (bold(_("Security Advisories")),darkred(_("cannot read the checksum, sorry")),)
|
||||
mytxt = "%s: %s." % (
|
||||
bold(_("Security Advisories")),
|
||||
darkred(_("cannot read the checksum, sorry")),
|
||||
)
|
||||
self.Entropy.updateProgress(
|
||||
mytxt,
|
||||
importance = 2,
|
||||
@@ -640,7 +730,10 @@ class SecurityInterface:
|
||||
self.Entropy._resources_run_remove_lock()
|
||||
return 4
|
||||
elif status == 3:
|
||||
mytxt = "%s: %s." % (bold(_("Security Advisories")),darkred(_("digest verification failed, sorry")),)
|
||||
mytxt = "%s: %s." % (
|
||||
bold(_("Security Advisories")),
|
||||
darkred(_("digest verification failed, sorry")),
|
||||
)
|
||||
self.Entropy.updateProgress(
|
||||
mytxt,
|
||||
importance = 2,
|
||||
@@ -650,7 +743,10 @@ class SecurityInterface:
|
||||
self.Entropy._resources_run_remove_lock()
|
||||
return 5
|
||||
elif status == 0:
|
||||
mytxt = "%s: %s." % (bold(_("Security Advisories")),darkgreen(_("verification Successful")),)
|
||||
mytxt = "%s: %s." % (
|
||||
bold(_("Security Advisories")),
|
||||
darkgreen(_("verification Successful")),
|
||||
)
|
||||
self.Entropy.updateProgress(
|
||||
mytxt,
|
||||
importance = 1,
|
||||
@@ -662,16 +758,23 @@ class SecurityInterface:
|
||||
raise InvalidData("InvalidData: %s." % (mytxt,))
|
||||
|
||||
# save downloaded md5
|
||||
if os.path.isfile(self.download_package_checksum) and os.path.isdir(etpConst['dumpstoragedir']):
|
||||
if os.path.isfile(self.download_package_checksum) and \
|
||||
os.path.isdir(etpConst['dumpstoragedir']):
|
||||
|
||||
if os.path.isfile(self.old_download_package_checksum):
|
||||
os.remove(self.old_download_package_checksum)
|
||||
shutil.copy2(self.download_package_checksum,self.old_download_package_checksum)
|
||||
self.Entropy.setup_default_file_perms(self.old_download_package_checksum)
|
||||
shutil.copy2(self.download_package_checksum,
|
||||
self.old_download_package_checksum)
|
||||
self.Entropy.setup_default_file_perms(
|
||||
self.old_download_package_checksum)
|
||||
|
||||
# now unpack in place
|
||||
status = self.__unpack_advisories()
|
||||
if status != 0:
|
||||
mytxt = "%s: %s." % (bold(_("Security Advisories")),darkred(_("digest verification failed, try again later")),)
|
||||
mytxt = "%s: %s." % (
|
||||
bold(_("Security Advisories")),
|
||||
darkred(_("digest verification failed, try again later")),
|
||||
)
|
||||
self.Entropy.updateProgress(
|
||||
mytxt,
|
||||
importance = 2,
|
||||
@@ -681,7 +784,11 @@ class SecurityInterface:
|
||||
self.Entropy._resources_run_remove_lock()
|
||||
return 6
|
||||
|
||||
mytxt = "%s: %s %s" % (bold(_("Security Advisories")),blue(_("installing")),red("..."),)
|
||||
mytxt = "%s: %s %s" % (
|
||||
bold(_("Security Advisories")),
|
||||
blue(_("installing")),
|
||||
red("..."),
|
||||
)
|
||||
self.Entropy.updateProgress(
|
||||
mytxt,
|
||||
importance = 1,
|
||||
|
||||
Reference in New Issue
Block a user