comparison farolluz/cvrf.py @ 18:8a89b7a591e6

merged
author Benoît Allard <benoit.allard@greenbone.net>
date Tue, 14 Oct 2014 16:49:36 +0200
parents 90852c11fabd
children 4b53e7bcff0d
comparison
equal deleted inserted replaced
3:8e23ba7d4167 18:8a89b7a591e6
63 self._aliases = [] 63 self._aliases = []
64 64
65 def addAlias(self, alias): 65 def addAlias(self, alias):
66 self._aliases.append(alias) 66 self._aliases.append(alias)
67 67
68 def getId(self):
69 return self._id
70
68 def validate(self): 71 def validate(self):
69 if not self._id: 72 if not self._id:
70 raise ValidationError('Document ID cannot be left empty') 73 raise ValidationError('Document ID cannot be left empty')
71 74
72 def __str__(self): 75 def __str__(self):
89 def addRevision(self, revision): 92 def addRevision(self, revision):
90 self._history.append(revision) 93 self._history.append(revision)
91 94
92 def setGenerator(self, generator): 95 def setGenerator(self, generator):
93 self._generator = generator 96 self._generator = generator
97
98 def getId(self):
99 return self._identification.getId()
94 100
95 def validate(self): 101 def validate(self):
96 if self._identification is None: 102 if self._identification is None:
97 raise ValidationError('Document Tracking needs to have an Identification') 103 raise ValidationError('Document Tracking needs to have an Identification')
98 self._identification.validate() 104 self._identification.validate()
223 if not self._description: 229 if not self._description:
224 raise ValidationError('A Reference must contain a description') 230 raise ValidationError('A Reference must contain a description')
225 231
226 232
227 class CVRFAcknowledgment(object): 233 class CVRFAcknowledgment(object):
228 def __init__(self, name=None, organization=None, description=None, 234 def __init__(self, names=[], organizations=[], description=None,
229 url=None): 235 url=None):
230 self._name = name 236 self._names = names
231 self._organization = organization 237 self._organizations = organizations
232 self._description = description 238 self._description = description
233 self._url = url 239 self._url = url
234 240
235 def getTitle(self): 241 def getTitle(self):
236 return "%s - %s" % (self._name, self._organization) 242 return "%s - %s" % (', '.join(self._names),
237 243 ', '.join(self._organizations))
238 def validate(self): 244
239 if (not self._name) and (not self._organization) and (not self._description): 245 def validate(self):
246 if (not self._names) and (not self._organizations) and (not self._description):
240 raise ValidationError('An Acknowledgment must have at least a Name, an Organization or a Description') 247 raise ValidationError('An Acknowledgment must have at least a Name, an Organization or a Description')
241 248
242 249
243 class CVRFProductTree(object): 250 class CVRFProductTree(object):
244 def __init__(self): 251 def __init__(self):
247 self._groups = [] 254 self._groups = []
248 self._relationships = [] 255 self._relationships = []
249 self._products = [] 256 self._products = []
250 self._groups = [] 257 self._groups = []
251 258
252 def addBranch(self, branch):
253 parent = self.getBranch(branch.getParent().getPath())
254 if parent is self:
255 self._branches.append(branch)
256 else:
257 parent._childs.append(branch)
258
259 def addProduct(self, product): 259 def addProduct(self, product):
260 if product not in self._products: 260 """ Add to the product list """
261 self._products.append(product) 261 self._products.append(product)
262 if product._parent is not self:
263 product._parent._product = product
264 262
265 def addRelationship(self, rel): 263 def addRelationship(self, rel):
266 self._relationships.append(rel) 264 self._relationships.append(rel)
267 265
268 def addGroup(self, group): 266 def addGroup(self, group):
394 'Patch Level', 'Service Pack', 'Architecture', 'Language', 392 'Patch Level', 'Service Pack', 'Architecture', 'Language',
395 'Legacy', 'Specification') 393 'Legacy', 'Specification')
396 def __init__(self, _type, name, parentbranch): 394 def __init__(self, _type, name, parentbranch):
397 self._type = _type 395 self._type = _type
398 self._name = name 396 self._name = name
399 self._parentbranch = parentbranch
400 self._childs = [] 397 self._childs = []
401 self._product = None 398 self._product = None
399 self.link(parentbranch)
402 400
403 def getParent(self): 401 def getParent(self):
404 return self._parentbranch 402 return self._parentbranch
405 403
406 def getPath(self, string=False): 404 def getPath(self, string=False):
453 self.getParent()._branches.remove(self) 451 self.getParent()._branches.remove(self)
454 else: 452 else:
455 self.getParent()._childs.remove(self) 453 self.getParent()._childs.remove(self)
456 self._parentbranch = None 454 self._parentbranch = None
457 455
456 def link(self, parent):
457 """ Actually, only set the parent """
458 self._parentbranch = parent
459 if self.isRoot():
460 parent._branches.append(self)
461 else:
462 parent._childs.append(self)
463
464
458 def validate(self): 465 def validate(self):
459 if not self._type: 466 if not self._type:
460 raise ValidationError('A Branch must have a Type') 467 raise ValidationError('A Branch must have a Type')
461 if self._type not in self.TYPES: 468 if self._type not in self.TYPES:
462 raise ValidationError('A Branch Type must be one of %s' % ', '.join(self.TYPES)) 469 raise ValidationError('A Branch Type must be one of %s' % ', '.join(self.TYPES))
473 480
474 class CVRFFullProductName(object): 481 class CVRFFullProductName(object):
475 def __init__(self, productid, name, parent, cpe=None): 482 def __init__(self, productid, name, parent, cpe=None):
476 self._productid = productid 483 self._productid = productid
477 self._name = name 484 self._name = name
485 self._cpe = cpe
478 # Can be None (directly under the tree), a ProductBranch, or a 486 # Can be None (directly under the tree), a ProductBranch, or a
479 # Relationship 487 # Relationship
480 self._parent = parent 488 self.link(parent)
481 self._cpe = cpe
482 489
483 def isRoot(self): 490 def isRoot(self):
484 return isinstance(self._parent, CVRFProductTree) 491 return isinstance(self._parent, CVRFProductTree)
485 492
486 def isRelationship(self): 493 def isRelationship(self):
500 if self.isRelationship(): 507 if self.isRelationship():
501 return self._parent 508 return self._parent
502 return None 509 return None
503 510
504 def unlink(self): 511 def unlink(self):
505 """ Unset our _parent, and remove us from the _parent._childs """ 512 """ Unset our _parent, and remove us from the _parent._childs
506 if self.isRoot(): 513 We are still in the product list.
507 self._parent._products.remove(self) 514 """
508 else: 515 if not self.isRoot():
509 self._parent._product = None 516 self._parent._product = None
510 self._parent = None 517 self._parent = None
518
519 def link(self, parent):
520 self._parent = parent
521 if not self.isRoot():
522 parent._product = self
511 523
512 def validate(self): 524 def validate(self):
513 if not self._productid: 525 if not self._productid:
514 raise ValidationError('A Product must have a ProductID') 526 raise ValidationError('A Product must have a ProductID')
515 if not self._name: 527 if not self._name:
653 return self._title 665 return self._title
654 if self._id: 666 if self._id:
655 return self._id._value 667 return self._id._value
656 return "#%d" % self._ordinal 668 return "#%d" % self._ordinal
657 669
670 def getNote(self, ordinal):
671 for note in self._notes:
672 if note._ordinal == ordinal:
673 return note
674 return None
675
676 def mentionsProdId(self, productid):
677 """ Returns in which sub element, self is mentioning the productid """
678 for category in (self._productstatuses, self._threats, self._cvsss, self._remediations):
679 for subelem in category:
680 if productid in subelem._productids:
681 yield subelem
682
683 def isMentioningProdId(self, productid):
684 """ Returns if self is mentioning the productid """
685 for e in self.mentionsProdId(productid):
686 # We only need to know if the generator yield at least one elem.
687 return True
688 return False
689
690 def mentionsGroupId(self, groupid):
691 for category in (self._threats, self._remediations):
692 for subelem in category:
693 if groupid in subelem._groupids:
694 yield subelem
695
696 def isMentioningGroupId(self, groupids):
697 """ Make sure you call this with a list (not a generator or a tuple)
698 when wished """
699 if not isinstance(groupids, list):
700 groupids = [groupids]
701 for groupid in groupids:
702 print "testing GroupId: ", groupid
703 for _ in self.mentionsGroupId(groupid):
704 # We only need to know if the generator yield at least one elem.
705 print 'True'
706 return True
707 print 'False'
708 return False
709
658 def validate(self, productids, groupids): 710 def validate(self, productids, groupids):
659 if not self._ordinal: 711 if not self._ordinal:
660 raise ValidationError('A Vulnerability must have an ordinal') 712 raise ValidationError('A Vulnerability must have an ordinal')
661 if self._id is not None: 713 if self._id is not None:
662 self._id.validate() 714 self._id.validate()
670 involvement.validate() 722 involvement.validate()
671 for cwe in self._cwes: 723 for cwe in self._cwes:
672 cwe.validate() 724 cwe.validate()
673 for status in self._productstatuses: 725 for status in self._productstatuses:
674 status.validate(productids) 726 status.validate(productids)
727 pids = set()
728 for status in self._productstatuses:
729 for pid in status._productids:
730 if pid in pids:
731 raise ValidationError('ProductID %s mentionned in two different ProductStatuses for Vulnerability %d' % (pid, self._ordinal))
732 pids.add(pid)
675 for threat in self._threats: 733 for threat in self._threats:
676 threat.validate(productids, groupids) 734 threat.validate(productids, groupids)
677 for cvss in self._cvsss: 735 for cvss in self._cvsss:
678 cvss.validate(productids) 736 cvss.validate(productids)
737 pids = set()
738 for cvss in self._cvsss:
739 for pid in (cvss._productids or productids):
740 if pid in pids:
741 raise ValidationError('ProductID %s mentionned in two different CVSS Score Sets for Vulnerability %d' % (pid, self._ordinal))
742 pids.add(pid)
679 for remediation in self._remediations: 743 for remediation in self._remediations:
680 remediation.validate(productids, groupids) 744 remediation.validate(productids, groupids)
681 for reference in self._references: 745 for reference in self._references:
682 reference.validate() 746 reference.validate()
683 for acknowledgment in self._acknowledgments: 747 for acknowledgment in self._acknowledgments:
684 acknowledgment.validate() 748 acknowledgment.validate()
685
686 749
687 750
688 class CVRFInvolvement(object): 751 class CVRFInvolvement(object):
689 PARTIES = CVRFPublisher.TYPES 752 PARTIES = CVRFPublisher.TYPES
690 STATUSES = ('Open', 'Disputed', 'In Progress', 'Completed', 753 STATUSES = ('Open', 'Disputed', 'In Progress', 'Completed',
724 787
725 788
726 class CVRFProductStatus(object): 789 class CVRFProductStatus(object):
727 TYPES = ('First Affected', 'Known Affected', 'Known Not Affected', 790 TYPES = ('First Affected', 'Known Affected', 'Known Not Affected',
728 'First Fixed', 'Fixed', 'Recommended', 'Last Affected') 791 'First Fixed', 'Fixed', 'Recommended', 'Last Affected')
792 NAME = "Product Status"
729 def __init__(self, _type): 793 def __init__(self, _type):
730 self._type = _type 794 self._type = _type
731 self._productids = [] 795 self._productids = []
732 796
733 def addProductID(self, productid): 797 def addProductID(self, productid):
748 raise ValidationError('Unknown ProductID: %s' % productid) 812 raise ValidationError('Unknown ProductID: %s' % productid)
749 813
750 814
751 class CVRFThreat(object): 815 class CVRFThreat(object):
752 TYPES = ('Impact', 'Exploit Status', 'Target Set') 816 TYPES = ('Impact', 'Exploit Status', 'Target Set')
817 NAME = "Threat"
753 def __init__(self, _type, description): 818 def __init__(self, _type, description):
754 self._type = _type 819 self._type = _type
755 self._description = description 820 self._description = description
756 self._date = None 821 self._date = None
757 self._productids = [] 822 self._productids = []
790 'AC': {'H':0.35, 'M':0.61 ,'L':0.71}, 855 'AC': {'H':0.35, 'M':0.61 ,'L':0.71},
791 'Au': {'M':0.45, 'S':0.56, 'N':0.704}, 856 'Au': {'M':0.45, 'S':0.56, 'N':0.704},
792 'C': {'N':0.0, 'P':0.275, 'C':0.66}, 857 'C': {'N':0.0, 'P':0.275, 'C':0.66},
793 'I': {'N':0.0, 'P':0.275, 'C':0.66}, 858 'I': {'N':0.0, 'P':0.275, 'C':0.66},
794 'A': {'N':0.0, 'P':0.275, 'C':0.66}} 859 'A': {'N':0.0, 'P':0.275, 'C':0.66}}
860 NAME = "CVSS Score Set"
795 def __init__(self, basescore): 861 def __init__(self, basescore):
796 self._basescore = basescore 862 self._basescore = basescore
797 self._temporalscore = None 863 self._temporalscore = None
798 self._environmentalscore = None 864 self._environmentalscore = None
799 self._vector = None 865 self._vector = None
842 908
843 909
844 class CVRFRemediation(object): 910 class CVRFRemediation(object):
845 TYPES = ('Workaround', 'Mitigation', 'Vendor Fix', 'None Available', 911 TYPES = ('Workaround', 'Mitigation', 'Vendor Fix', 'None Available',
846 'Will Not Fix') 912 'Will Not Fix')
913 NAME = "Remediation"
847 def __init__(self, _type, description): 914 def __init__(self, _type, description):
848 self._type = _type 915 self._type = _type
849 self._description = description 916 self._description = description
850 self._date = None 917 self._date = None
851 self._entitlement = None 918 self._entitlement = None
970 continue 1037 continue
971 for productid in status._productids: 1038 for productid in status._productids:
972 products.add(productid) 1039 products.add(productid)
973 return set(self.getProductForID(p) for p in products) 1040 return set(self.getProductForID(p) for p in products)
974 1041
1042 def isProductOrphan(self, productid):
1043 """ Returns if a productid is mentionned nowhere in the document """
1044 # We first look at the ProductTree
1045 ptree = self._producttree
1046 for relation in ptree._relationships:
1047 if productid == relation._productreference:
1048 return False
1049 if productid == relation._relatestoproductreference:
1050 return False
1051 groupids = [g._groupid for g in ptree._groups if productid in g._productids]
1052 if len(groupids) > 0:
1053 return False
1054 # Go through all the Vulnerabilities
1055 for vulnerability in self._vulnerabilities:
1056 if vulnerability.isMentioningProdId(productid):
1057 return False
1058 for groupid in groupids:
1059 if vulnerability.isMentioningGroupId(groupid):
1060 return False
1061 return True
1062
975 def getNote(self, ordinal): 1063 def getNote(self, ordinal):
976 for note in self._notes: 1064 for note in self._notes:
977 if note._ordinal == ordinal: 1065 if note._ordinal == ordinal:
978 return note 1066 return note
979 return None 1067 return None
1068
1069 def getDocId(self):
1070 if self._tracking is not None:
1071 return self._tracking.getId()
1072 # Make up something ...
1073 return self._title.lower()
980 1074
981 def validate(self): 1075 def validate(self):
982 if not self._title: 1076 if not self._title:
983 raise ValidationError('Document Title cannot be empty') 1077 raise ValidationError('Document Title cannot be empty')
984 if not self._type: 1078 if not self._type:
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)