Package entropy :: Module security

Source Code for Module entropy.security

  1  # -*- coding: utf-8 -*- 
  2  ''' 
  3      # DESCRIPTION: 
  4      # Entropy Object Oriented Interface 
  5   
  6      Copyright (C) 2007-2009 Fabio Erculiani 
  7   
  8      This program is free software; you can redistribute it and/or modify 
  9      it under the terms of the GNU General Public License as published by 
 10      the Free Software Foundation; either version 2 of the License, or 
 11      (at your option) any later version. 
 12   
 13      This program is distributed in the hope that it will be useful, 
 14      but WITHOUT ANY WARRANTY; without even the implied warranty of 
 15      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 16      GNU General Public License for more details. 
 17   
 18      You should have received a copy of the GNU General Public License 
 19      along with this program; if not, write to the Free Software 
 20      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 21  ''' 
 22  # pylint ~ ok 
 23  import os 
 24  import shutil 
 25  from entropy.exceptions import IncorrectParameter, InvalidData 
 26  from entropy.const import etpConst, etpCache, etpUi, const_setup_perms 
 27  from entropy.i18n import _ 
 28  from entropy.output import blue, bold, red, darkgreen, darkred 
 29   
30 -class SecurityInterface:
31 32 """ 33 ~~ GIVES YOU WINGS ~~ 34 """ 35 36 # thanks to Gentoo "gentoolkit" package, License below: 37 38 # This program is licensed under the GPL, version 2 39 40 # WARNING: this code is only tested by a few people and should NOT be used 41 # on production systems at this stage. 42 # There are possible security holes and probably 43 # bugs in this code. If you test it please report ANY success or failure to 44 # me (genone@gentoo.org). 45 46 # The following planned features are currently on hold: 47 # - getting GLSAs from http/ftp servers 48 # (not really useful without the fixed ebuilds) 49 # - GPG signing/verification (until key policy is clear) 50 51 import entropy.tools as entropyTools
52 - def __init__(self, EquoInstance):
53 54 # disabled for now 55 from entropy.client.interfaces import Client 56 if not isinstance(EquoInstance, Client): 57 mytxt = _("A valid Client interface instance is needed") 58 raise IncorrectParameter("IncorrectParameter: %s" % (mytxt,)) 59 60 self.Entropy = EquoInstance 61 from entropy.cache import EntropyCacher 62 self.__cacher = EntropyCacher() 63 from entropy.core import SystemSettings 64 self.SystemSettings = SystemSettings() 65 self.lastfetch = None 66 self.previous_checksum = "0" 67 self.advisories_changed = None 68 self.adv_metadata = None 69 self.affected_atoms = None 70 71 from xml.dom import minidom 72 self.minidom = minidom 73 74 self.op_mappings = { 75 "le": "<=", 76 "lt": "<", 77 "eq": "=", 78 "gt": ">", 79 "ge": ">=", 80 "rge": ">=", # >=~ 81 "rle": "<=", # <=~ 82 "rgt": ">", # >~ 83 "rlt": "<" # <~ 84 } 85 86 security_url = \ 87 self.SystemSettings['repositories']['security_advisories_url'] 88 security_file = os.path.basename(security_url) 89 md5_ext = etpConst['packagesmd5fileext'] 90 91 self.unpackdir = os.path.join(etpConst['entropyunpackdir'], 92 "security-%s" % (self.entropyTools.get_random_number(),)) 93 self.security_url = security_url 94 self.unpacked_package = os.path.join(self.unpackdir, "glsa_package") 95 self.security_url_checksum = security_url + md5_ext 96 97 self.download_package = os.path.join(self.unpackdir, security_file) 98 self.download_package_checksum = self.download_package + md5_ext 99 self.old_download_package_checksum = os.path.join( 100 etpConst['dumpstoragedir'], os.path.basename(security_url) 101 ) + md5_ext 102 103 self.security_package = os.path.join(etpConst['securitydir'], 104 os.path.basename(security_url)) 105 self.security_package_checksum = self.security_package + md5_ext 106 107 try: 108 109 if os.path.isfile(etpConst['securitydir']) or \ 110 os.path.islink(etpConst['securitydir']): 111 os.remove(etpConst['securitydir']) 112 113 if not os.path.isdir(etpConst['securitydir']): 114 os.makedirs(etpConst['securitydir'], 0775) 115 116 except OSError: 117 pass 118 const_setup_perms(etpConst['securitydir'], etpConst['entropygid']) 119 120 if os.access(self.old_download_package_checksum, os.F_OK | os.R_OK): 121 f_down = open(self.old_download_package_checksum) 122 try: 123 self.previous_checksum = f_down.readline().strip().split()[0] 124 except (IndexError, OSError, IOError,): 125 pass 126 f_down.close()
127
128 - def __prepare_unpack(self):
129 130 if os.path.isfile(self.unpackdir) or os.path.islink(self.unpackdir): 131 os.remove(self.unpackdir) 132 133 if os.path.isdir(self.unpackdir): 134 shutil.rmtree(self.unpackdir, True) 135 try: 136 os.rmdir(self.unpackdir) 137 except OSError: 138 pass 139 140 os.makedirs(self.unpackdir, 0775) 141 const_setup_perms(self.unpackdir, etpConst['entropygid'])
142
143 - def __download_glsa_package(self):
144 return self.__generic_download(self.security_url, self.download_package)
145
147 return self.__generic_download(self.security_url_checksum, 148 self.download_package_checksum, show_speed = False)
149
150 - def __generic_download(self, url, save_to, show_speed = True):
151 fetcher = self.Entropy.urlFetcher(url, save_to, resume = False, 152 show_speed = show_speed) 153 fetcher.progress = self.Entropy.progress 154 rc_fetch = fetcher.download() 155 del fetcher 156 if rc_fetch in ("-1", "-2", "-3", "-4"): 157 return False 158 # setup permissions 159 self.Entropy.setup_default_file_perms(save_to) 160 return True
161
162 - def __verify_checksum(self):
163 164 # read checksum 165 if not os.path.isfile(self.download_package_checksum) or \ 166 not os.access(self.download_package_checksum, os.R_OK): 167 return 1 168 169 f_down = open(self.download_package_checksum) 170 read_err = False 171 try: 172 checksum = f_down.readline().strip().split()[0] 173 except (OSError, IOError, IndexError,): 174 read_err = True 175 176 f_down.close() 177 if read_err: 178 return 2 179 180 self.advisories_changed = True 181 if checksum == self.previous_checksum: 182 self.advisories_changed = False 183 184 md5res = self.entropyTools.compare_md5(self.download_package, checksum) 185 if not md5res: 186 return 3 187 return 0
188
189 - def __unpack_advisories(self):
190 rc_unpack = self.entropyTools.uncompress_tar_bz2( 191 self.download_package, 192 self.unpacked_package, 193 catchEmpty = True 194 ) 195 const_setup_perms(self.unpacked_package, etpConst['entropygid']) 196 return rc_unpack
197
199 if os.listdir(etpConst['securitydir']): 200 shutil.rmtree(etpConst['securitydir'], True) 201 if not os.path.isdir(etpConst['securitydir']): 202 os.makedirs(etpConst['securitydir'], 0775) 203 const_setup_perms(self.unpackdir, etpConst['entropygid'])
204
206 for advfile in os.listdir(self.unpacked_package): 207 from_file = os.path.join(self.unpacked_package, advfile) 208 to_file = os.path.join(etpConst['securitydir'], advfile) 209 shutil.move(from_file, to_file)
210
211 - def __cleanup_garbage(self):
212 shutil.rmtree(self.unpackdir, True)
213
214 - def clear(self, xcache = False):
215 self.adv_metadata = None 216 if xcache: 217 self.Entropy.clear_dump_cache(etpCache['advisories'])
218
219 - def get_advisories_cache(self):
220 221 if self.adv_metadata != None: 222 return self.adv_metadata 223 224 if self.Entropy.xcache: 225 dir_checksum = self.entropyTools.md5sum_directory( 226 etpConst['securitydir']) 227 c_hash = "%s%s" % ( 228 etpCache['advisories'], hash("%s|%s|%s" % ( 229 hash(self.SystemSettings['repositories']['branch']), 230 hash(dir_checksum), 231 hash(etpConst['systemroot']), 232 )), 233 ) 234 adv_metadata = self.__cacher.pop(c_hash) 235 if adv_metadata != None: 236 self.adv_metadata = adv_metadata.copy() 237 return self.adv_metadata
238
239 - def set_advisories_cache(self, adv_metadata):
240 if self.Entropy.xcache: 241 dir_checksum = self.entropyTools.md5sum_directory( 242 etpConst['securitydir']) 243 c_hash = "%s%s" % ( 244 etpCache['advisories'], hash("%s|%s|%s" % ( 245 hash(self.SystemSettings['repositories']['branch']), 246 hash(dir_checksum), 247 hash(etpConst['systemroot']), 248 )), 249 ) 250 self.__cacher.push(c_hash, adv_metadata)
251
252 - def get_advisories_list(self):
253 if not self.check_advisories_availability(): 254 return [] 255 xmls = os.listdir(etpConst['securitydir']) 256 xmls = sorted([x for x in xmls if x.endswith(".xml") and \ 257 x.startswith("glsa-")]) 258 return xmls
259
260 - def get_advisories_metadata(self):
261 262 cached = self.get_advisories_cache() 263 if cached != None: 264 return cached 265 266 adv_metadata = {} 267 xmls = self.get_advisories_list() 268 maxlen = len(xmls) 269 count = 0 270 for xml in xmls: 271 272 count += 1 273 if not etpUi['quiet']: 274 self.Entropy.updateProgress(":: " + \ 275 str(round((float(count)/maxlen)*100,1)) + "% ::", 276 importance = 0, type = "info", back = True) 277 278 xml_metadata = None 279 exc_string = "" 280 exc_err = "" 281 try: 282 xml_metadata = self.get_xml_metadata(xml) 283 except KeyboardInterrupt: 284 return {} 285 except Exception, err: 286 exc_string = unicode(Exception) 287 exc_err = unicode(err) 288 if xml_metadata == None: 289 more_info = "" 290 if exc_string: 291 mytxt = _("Error") 292 more_info = " %s: %s: %s" % (mytxt, exc_string, exc_err,) 293 mytxt = "%s: %s: %s! %s" % ( 294 blue(_("Warning")), 295 bold(xml), 296 blue(_("advisory broken")), 297 more_info, 298 ) 299 self.Entropy.updateProgress( 300 mytxt, 301 importance = 1, 302 type = "warning", 303 header = red(" !!! ") 304 ) 305 continue 306 elif not xml_metadata: 307 continue 308 adv_metadata.update(xml_metadata) 309 310 adv_metadata = self.filter_advisories(adv_metadata) 311 self.set_advisories_cache(adv_metadata) 312 self.adv_metadata = adv_metadata.copy() 313 return adv_metadata
314 315 # this function filters advisories for packages that aren't 316 # in the repositories. Note: only keys will be matched
317 - def filter_advisories(self, adv_metadata):
318 keys = adv_metadata.keys() 319 for key in keys: 320 valid = True 321 if adv_metadata[key]['affected']: 322 affected = adv_metadata[key]['affected'] 323 affected_keys = affected.keys() 324 valid = False 325 skipping_keys = set() 326 for a_key in affected_keys: 327 match = self.Entropy.atom_match(a_key) 328 if match[0] != -1: 329 # it's in the repos, it's valid 330 valid = True 331 else: 332 skipping_keys.add(a_key) 333 if not valid: 334 del adv_metadata[key] 335 for a_key in skipping_keys: 336 try: 337 del adv_metadata[key]['affected'][a_key] 338 except KeyError: 339 continue 340 try: 341 if not adv_metadata[key]['affected']: 342 del adv_metadata[key] 343 except KeyError: 344 continue 345 346 return adv_metadata
347
348 - def is_affected(self, adv_key, adv_data = None):
349 if not adv_data: 350 adv_data = self.get_advisories_metadata() 351 if adv_key not in adv_data: 352 return False 353 mydata = adv_data[adv_key].copy() 354 del adv_data 355 356 if not mydata['affected']: 357 return False 358 359 for key in mydata['affected']: 360 361 vul_atoms = mydata['affected'][key][0]['vul_atoms'] 362 unaff_atoms = mydata['affected'][key][0]['unaff_atoms'] 363 unaffected_atoms = set() 364 if not vul_atoms: 365 return False 366 for atom in unaff_atoms: 367 matches = self.Entropy.clientDbconn.atomMatch(atom, 368 multiMatch = True) 369 for idpackage in matches[0]: 370 unaffected_atoms.add((idpackage, 0)) 371 372 for atom in vul_atoms: 373 match = self.Entropy.clientDbconn.atomMatch(atom) 374 if (match[0] != -1) and (match not in unaffected_atoms): 375 if self.affected_atoms == None: 376 self.affected_atoms = set() 377 self.affected_atoms.add(atom) 378 return True 379 return False
380
381 - def get_vulnerabilities(self):
382 return self.get_affection()
383
385 return self.get_affection(affected = False)
386 387 # if not affected: not affected packages will be returned 388 # if affected: affected packages will be returned
389 - def get_affection(self, affected = True):
390 adv_data = self.get_advisories_metadata() 391 adv_data_keys = adv_data.keys() 392 valid_keys = set() 393 for adv in adv_data_keys: 394 is_affected = self.is_affected(adv, adv_data) 395 if affected == is_affected: 396 valid_keys.add(adv) 397 # we need to filter our adv_data and return 398 for key in adv_data_keys: 399 if key not in valid_keys: 400 try: 401 del adv_data[key] 402 except KeyError: 403 pass 404 # now we need to filter packages in adv_dat 405 for adv in adv_data: 406 for key in adv_data[adv]['affected'].keys(): 407 atoms = adv_data[adv]['affected'][key][0]['vul_atoms'] 408 applicable = True 409 for atom in atoms: 410 if atom in self.affected_atoms: 411 applicable = False 412 break 413 if applicable == affected: 414 del adv_data[adv]['affected'][key] 415 return adv_data
416
417 - def get_affected_atoms(self):
418 adv_data = self.get_advisories_metadata() 419 adv_data_keys = adv_data.keys() 420 del adv_data 421 self.affected_atoms = set() 422 for key in adv_data_keys: 423 self.is_affected(key) 424 return self.affected_atoms
425
426 - def get_xml_metadata(self, xmlfilename):
427 428 xml_data = {} 429 xmlfile = os.path.join(etpConst['securitydir'], xmlfilename) 430 try: 431 xmldoc = self.minidom.parse(xmlfile) 432 except: 433 return None 434 435 # get base data 436 glsa_tree = xmldoc.getElementsByTagName("glsa")[0] 437 glsa_product = glsa_tree.getElementsByTagName("product")[0] 438 if glsa_product.getAttribute("type") != "ebuild": 439 return {} 440 441 glsa_id = glsa_tree.getAttribute("id") 442 glsa_title = glsa_tree.getElementsByTagName("title")[0] 443 glsa_title = glsa_title.firstChild.data 444 glsa_synopsis = glsa_tree.getElementsByTagName("synopsis")[0] 445 glsa_synopsis = glsa_synopsis.firstChild.data 446 glsa_announced = glsa_tree.getElementsByTagName("announced")[0] 447 glsa_announced = glsa_announced.firstChild.data 448 glsa_revised = glsa_tree.getElementsByTagName("revised")[0] 449 glsa_revised = glsa_revised.firstChild.data 450 451 xml_data['filename'] = xmlfilename 452 xml_data['url'] = "http://www.gentoo.org/security/en/glsa/%s" % ( 453 xmlfilename,) 454 xml_data['title'] = glsa_title.strip() 455 xml_data['synopsis'] = glsa_synopsis.strip() 456 xml_data['announced'] = glsa_announced.strip() 457 xml_data['revised'] = glsa_revised.strip() 458 xml_data['bugs'] = ["https://bugs.gentoo.org/" + \ 459 x.firstChild.data.strip() for x in \ 460 glsa_tree.getElementsByTagName("bug")] 461 462 try: 463 glsa_access = glsa_tree.getElementsByTagName("access")[0] 464 xml_data['access'] = glsa_access.firstChild.data.strip() 465 except IndexError: 466 xml_data['access'] = "" 467 468 # references 469 references = glsa_tree.getElementsByTagName("references")[0] 470 xml_data['references'] = [x.getAttribute("link").strip() for x in \ 471 references.getElementsByTagName("uri")] 472 473 try: 474 xml_data['description_items'] = [] 475 desc = glsa_tree.getElementsByTagName("description")[0] 476 desc = desc.getElementsByTagName("p")[0].firstChild.data.strip() 477 xml_data['description'] = desc 478 items = glsa_tree.getElementsByTagName("description")[0] 479 for item in items.getElementsByTagName("ul"): 480 li_items = item.getElementsByTagName("li") 481 for li_item in li_items: 482 xml_data['description_items'].append(' '.join( 483 [x.strip() for x in \ 484 li_item.firstChild.data.strip().split("\n")]) 485 ) 486 except IndexError: 487 xml_data['description'] = "" 488 xml_data['description_items'] = [] 489 490 try: 491 workaround = glsa_tree.getElementsByTagName("workaround")[0] 492 workaround_p = workaround.getElementsByTagName("p")[0] 493 xml_data['workaround'] = workaround_p.firstChild.data.strip() 494 except IndexError: 495 xml_data['workaround'] = "" 496 497 try: 498 xml_data['resolution'] = [] 499 resolution = glsa_tree.getElementsByTagName("resolution")[0] 500 p_elements = resolution.getElementsByTagName("p") 501 for p_elem in p_elements: 502 xml_data['resolution'].append(p_elem.firstChild.data.strip()) 503 except IndexError: 504 xml_data['resolution'] = [] 505 506 try: 507 impact = glsa_tree.getElementsByTagName("impact")[0] 508 impact_p = impact.getElementsByTagName("p")[0] 509 xml_data['impact'] = impact_p.firstChild.data.strip() 510 except IndexError: 511 xml_data['impact'] = "" 512 impact_type = glsa_tree.getElementsByTagName("impact")[0] 513 xml_data['impacttype'] = impact_type.getAttribute("type").strip() 514 515 try: 516 background = glsa_tree.getElementsByTagName("background")[0] 517 background_p = background.getElementsByTagName("p")[0] 518 xml_data['background'] = background_p.firstChild.data.strip() 519 except IndexError: 520 xml_data['background'] = "" 521 522 # affection information 523 affected = glsa_tree.getElementsByTagName("affected")[0] 524 affected_packages = {} 525 # we will then filter affected_packages using repositories information 526 # if not affected_packages: advisory will be dropped 527 for pkg in affected.getElementsByTagName("package"): 528 name = pkg.getAttribute("name") 529 if not affected_packages.has_key(name): 530 affected_packages[name] = [] 531 532 pdata = {} 533 pdata["arch"] = pkg.getAttribute("arch").strip() 534 pdata["auto"] = (pkg.getAttribute("auto") == "yes") 535 pdata["vul_vers"] = [self.__make_version(v) for v in \ 536 pkg.getElementsByTagName("vulnerable")] 537 pdata["unaff_vers"] = [self.__make_version(v) for v in \ 538 pkg.getElementsByTagName("unaffected")] 539 pdata["vul_atoms"] = [self.__make_atom(name, v) for v \ 540 in pkg.getElementsByTagName("vulnerable")] 541 pdata["unaff_atoms"] = [self.__make_atom(name, v) for v \ 542 in pkg.getElementsByTagName("unaffected")] 543 affected_packages[name].append(pdata) 544 xml_data['affected'] = affected_packages.copy() 545 546 return {glsa_id: xml_data}
547
548 - def __make_version(self, vnode):
549 """ 550 creates from the information in the I{versionNode} a 551 version string (format <op><version>). 552 553 @type vnode: xml.dom.Node 554 @param vnode: a <vulnerable> or <unaffected> Node that 555 contains the version information for this atom 556 @rtype: String 557 @return: the version string 558 """ 559 return self.op_mappings[vnode.getAttribute("range")] + \ 560 vnode.firstChild.data.strip()
561
562 - def __make_atom(self, pkgname, vnode):
563 """ 564 creates from the given package name and information in the 565 I{versionNode} a (syntactical) valid portage atom. 566 567 @type pkgname: String 568 @param pkgname: the name of the package for this atom 569 @type vnode: xml.dom.Node 570 @param vnode: a <vulnerable> or <unaffected> Node that 571 contains the version information for this atom 572 @rtype: String 573 @return: the portage atom 574 """ 575 return str(self.op_mappings[vnode.getAttribute("range")] + pkgname + \ 576 "-" + vnode.firstChild.data.strip())
577
579 if not os.path.lexists(etpConst['securitydir']): 580 return False 581 if not os.path.isdir(etpConst['securitydir']): 582 return False 583 else: 584 return True 585 return False
586
587 - def fetch_advisories(self, do_cache = True):
588 589 mytxt = "%s: %s" % ( 590 bold(_("Security Advisories")), 591 blue(_("testing service connection")), 592 ) 593 self.Entropy.updateProgress( 594 mytxt, 595 importance = 2, 596 type = "info", 597 header = red(" @@ "), 598 footer = red(" ...") 599 ) 600 601 mytxt = "%s: %s %s" % ( 602 bold(_("Security Advisories")), 603 blue(_("getting latest GLSAs")), 604 red("..."), 605 ) 606 self.Entropy.updateProgress( 607 mytxt, 608 importance = 2, 609 type = "info", 610 header = red(" @@ ") 611 ) 612 613 gave_up = self.Entropy.lock_check( 614 self.Entropy.resources_check_lock) 615 if gave_up: 616 return 7 617 618 locked = self.Entropy.application_lock_check() 619 if locked: 620 self.Entropy.resources_remove_lock() 621 return 4 622 623 # lock 624 self.Entropy.resources_create_lock() 625 try: 626 rc_lock = self.run_fetch() 627 except: 628 self.Entropy.resources_remove_lock() 629 raise 630 if rc_lock != 0: 631 return rc_lock 632 633 self.Entropy.resources_remove_lock() 634 635 if self.advisories_changed: 636 advtext = "%s: %s" % ( 637 bold(_("Security Advisories")), 638 darkgreen(_("updated successfully")), 639 ) 640 else: 641 advtext = "%s: %s" % ( 642 bold(_("Security Advisories")), 643 darkgreen(_("already up to date")), 644 ) 645 646 if do_cache and self.Entropy.xcache: 647 self.get_advisories_metadata() 648 self.Entropy.updateProgress( 649 advtext, 650 importance = 2, 651 type = "info", 652 header = red(" @@ ") 653 ) 654 655 return 0
656
657 - def run_fetch(self):
658 # prepare directories 659 self.__prepare_unpack() 660 661 # download package 662 status = self.__download_glsa_package() 663 self.lastfetch = status 664 if not status: 665 mytxt = "%s: %s." % ( 666 bold(_("Security Advisories")), 667 darkred(_("unable to download the package, sorry")), 668 ) 669 self.Entropy.updateProgress( 670 mytxt, 671 importance = 2, 672 type = "error", 673 header = red(" ## ") 674 ) 675 self.Entropy.resources_remove_lock() 676 return 1 677 678 mytxt = "%s: %s %s" % ( 679 bold(_("Security Advisories")), 680 blue(_("Verifying checksum")), 681 red("..."), 682 ) 683 self.Entropy.updateProgress( 684 mytxt, 685 importance = 1, 686 type = "info", 687 header = red(" # "), 688 back = True 689 ) 690 691 # download digest 692 status = self.__download_glsa_package_cksum() 693 if not status: 694 mytxt = "%s: %s." % ( 695 bold(_("Security Advisories")), 696 darkred(_("cannot download the checksum, sorry")), 697 ) 698 self.Entropy.updateProgress( 699 mytxt, 700 importance = 2, 701 type = "error", 702 header = red(" ## ") 703 ) 704 self.Entropy.resources_remove_lock() 705 return 2 706 707 # verify digest 708 status = self.__verify_checksum() 709 710 if status == 1: 711 mytxt = "%s: %s." % ( 712 bold(_("Security Advisories")), 713 darkred(_("cannot open packages, sorry")), 714 ) 715 self.Entropy.updateProgress( 716 mytxt, 717 importance = 2, 718 type = "error", 719 header = red(" ## ") 720 ) 721 self.Entropy.resources_remove_lock() 722 return 3 723 elif status == 2: 724 mytxt = "%s: %s." % ( 725 bold(_("Security Advisories")), 726 darkred(_("cannot read the checksum, sorry")), 727 ) 728 self.Entropy.updateProgress( 729 mytxt, 730 importance = 2, 731 type = "error", 732 header = red(" ## ") 733 ) 734 self.Entropy.resources_remove_lock() 735 return 4 736 elif status == 3: 737 mytxt = "%s: %s." % ( 738 bold(_("Security Advisories")), 739 darkred(_("digest verification failed, sorry")), 740 ) 741 self.Entropy.updateProgress( 742 mytxt, 743 importance = 2, 744 type = "error", 745 header = red(" ## ") 746 ) 747 self.Entropy.resources_remove_lock() 748 return 5 749 elif status == 0: 750 mytxt = "%s: %s." % ( 751 bold(_("Security Advisories")), 752 darkgreen(_("verification Successful")), 753 ) 754 self.Entropy.updateProgress( 755 mytxt, 756 importance = 1, 757 type = "info", 758 header = red(" # ") 759 ) 760 else: 761 mytxt = _("Return status not valid") 762 raise InvalidData("InvalidData: %s." % (mytxt,)) 763 764 # save downloaded md5 765 if os.path.isfile(self.download_package_checksum) and \ 766 os.path.isdir(etpConst['dumpstoragedir']): 767 768 if os.path.isfile(self.old_download_package_checksum): 769 os.remove(self.old_download_package_checksum) 770 shutil.copy2(self.download_package_checksum, 771 self.old_download_package_checksum) 772 self.Entropy.setup_default_file_perms( 773 self.old_download_package_checksum) 774 775 # now unpack in place 776 status = self.__unpack_advisories() 777 if status != 0: 778 mytxt = "%s: %s." % ( 779 bold(_("Security Advisories")), 780 darkred(_("digest verification failed, try again later")), 781 ) 782 self.Entropy.updateProgress( 783 mytxt, 784 importance = 2, 785 type = "error", 786 header = red(" ## ") 787 ) 788 self.Entropy.resources_remove_lock() 789 return 6 790 791 mytxt = "%s: %s %s" % ( 792 bold(_("Security Advisories")), 793 blue(_("installing")), 794 red("..."), 795 ) 796 self.Entropy.updateProgress( 797 mytxt, 798 importance = 1, 799 type = "info", 800 header = red(" # ") 801 ) 802 803 # clear previous 804 self.__clear_previous_advisories() 805 # copy over 806 self.__put_advisories_in_place() 807 # remove temp stuff 808 self.__cleanup_garbage() 809 return 0
810