1+ import warnings
2+
3+
14class CPE (object ):
25 """
36 CPE class offers an API for basic CPE objects.
@@ -52,14 +55,18 @@ def __init__(self, osmatch_dict):
5255
5356 # create osclass list
5457 self ._osclasses = []
55- for _osclass in osmatch_dict ['osclasses' ]:
56- try :
57- _osclassobj = NmapOSClass (_osclass )
58- except :
59- raise Exception ("Could not create NmapOSClass object" )
60- self ._osclasses .append (_osclassobj )
61-
62- def add_class (self , class_dict ):
58+ try :
59+ for _osclass in osmatch_dict ['osclasses' ]:
60+ try :
61+ _osclassobj = NmapOSClass (_osclass )
62+ except :
63+ raise Exception ("Could not create NmapOSClass object" )
64+ self ._osclasses .append (_osclassobj )
65+ except KeyError :
66+ pass
67+
68+ def add_osclass (self , class_dict ):
69+
6370 """
6471 Add a NmapOSClass object to the OSMatch object. This method is
6572 useful to implement compatibility with older versions of NMAP
@@ -144,6 +151,16 @@ def __init__(self, osclass_dict):
144151 for _cpe in osclass_dict ['cpe' ]:
145152 self ._cpelist .append (CPE (_cpe ))
146153
154+ @property
155+ def cpelist (self ):
156+ """
157+ Returns a list of CPE Objects matching with this os class
158+
159+ :return: list of CPE objects
160+ :rtype: Array
161+ """
162+ return self ._cpelist
163+
147164 @property
148165 def vendor (self ):
149166 """
@@ -208,24 +225,68 @@ def __init__(self, osfp_data):
208225 self .__osmatches = []
209226 self .__ports_used = []
210227 self .__fingerprints = []
211- _osclasses = []
212228
213229 if 'osmatches' in osfp_data :
214230 for _osmatch in osfp_data ['osmatches' ]:
215231 _osmatch_obj = NmapOSMatch (_osmatch )
216232 self .__osmatches .append (_osmatch_obj )
217233 if 'osclasses' in osfp_data :
218- _osclasses = osfp_data ['osclasses' ]
219- if 'ports_used' in osfp_data :
220- self .__ports_used = osfp_data ['ports_used' ]
234+ for _osclass in osfp_data ['osclasses' ]:
235+ _osclass_obj = NmapOSClass (_osclass )
236+ _osmatched = self .get_osmatch (_osclass_obj )
237+ if _osmatched is not None :
238+ _osmatched .add_osclass (_osclass_obj )
239+ else :
240+ self ._add_dummy_osmatch (_osclass_obj )
221241 if 'osfingerprints' in osfp_data :
222242 for _osfp in osfp_data ['osfingerprints' ]:
223243 if 'fingerprint' in _osfp :
224244 self .__fingerprints .append (_osfp ['fingerprint' ])
245+ if 'ports_used' in osfp_data :
246+ self .__ports_used = osfp_data ['ports_used' ]
247+
248+ def get_osmatch (self , accuracy ):
249+ """
250+ This function enables NmapOSFingerprint to determine if an
251+ NmapOSClass object could be attached to an existing NmapOSMatch
252+ object in order to respect the common interface for
253+ the nmap xml version < 1.04 and >= 1.04
254+
255+ :return: an NmapOSMatch object matching with the NmapOSClass
256+ provided in parameter (match is performed based on accuracy)
257+ """
258+ rval = None
259+ for _osmatch in self .__osmatches :
260+ if _osmatch .accuracy == accuracy :
261+ rval = _osmatch
262+ break # sorry
263+ return rval
264+
265+ def _add_dummy_osmatch (self , osclass_obj ):
266+ """
267+ This functions creates a dummy NmapOSMatch object in order to
268+ encapsulate an NmapOSClass object which was not matched with an
269+ existing NmapOSMatch object
270+ """
271+ _dname = "{0}:{1}:{2}" .format (osclass_obj .type ,
272+ osclass_obj .vendor ,
273+ osclass_obj .osfamily )
274+ _dummy_dict = {'osmatch' : {'name' : _dname ,
275+ 'accuracy' : osclass_obj .accuracy ,
276+ 'line' : - 1 },
277+ 'osclasses' : []}
278+ _dummy_osmatch = NmapOSMatch (_dummy_dict )
279+ self .__osmatches .append (_dummy_osmatch )
225280
226281 @property
227- def osmatches (self ):
228- return self .__osmatches
282+ def osmatches (self , min_accuracy = 0 ):
283+ _osmatches = []
284+
285+ for _osmatch in self .__osmatches :
286+ if _osmatch .accuracy >= min_accuracy :
287+ _osmatches .append (_osmatch )
288+
289+ return _osmatches
229290
230291 @property
231292 def fingerprint (self ):
@@ -235,48 +296,28 @@ def fingerprint(self):
235296 def fingerprints (self ):
236297 return self .__fingerprints
237298
238- # for _osclass in _osclasses:
239- # _matched = self.is_matched(_osclass)
240- #
241- # __sortfct = lambda osent: int(osent['accuracy'])
242- # if 'osmatch' in osfp_data:
243- # try:
244- # self.__osmatch = sorted(osfp_data['osmatch'],
245- # key=__sortfct,
246- # reverse=True)
247- # except (KeyError, TypeError):
248- # self.__osmatch = []
249- #
250- # if 'osclass' in osfp_data:
251- # try:
252- # self.__osclass = sorted(osfp_data['osclass'],
253- # key=__sortfct,
254- # reverse=True)
255- # except (KeyError, TypeError):
256- # self.__osclass = []
257-
258299 def osmatch (self , min_accuracy = 90 ):
300+ warnings .warn ("NmapOSFingerprint.osmatch is deprecated: "
301+ "use NmapOSFingerprint.osmatches" , DeprecationWarning )
259302 os_array = []
260- for match_entry in self .__osmatch :
261- try :
262- if int (match_entry ['accuracy' ]) >= min_accuracy :
263- os_array .append (match_entry ['name' ])
264- except (KeyError , TypeError ):
265- pass
303+ for _osmatch in self .__osmatches :
304+ if _osmatch .accuracy >= min_accuracy :
305+ os_array .append (_osmatch .name )
266306 return os_array
267307
268308 def osclass (self , min_accuracy = 90 ):
309+ warnings .warn ("NmapOSFingerprint.osclass() is deprecated: "
310+ "use NmapOSFingerprint.osclasses() if applicable" ,
311+ DeprecationWarning )
269312 os_array = []
270- for osclass_entry in self .__osclass :
271- try :
272- if int ( osclass_entry [ 'accuracy' ]) >= min_accuracy :
273- _relevantkeys = [ ' type' , ' vendor' , ' osfamily' , 'osgen' ]
274- _ftstr = "|" . join ([ vkey + ": " + osclass_entry [ vkey ]
275- for vkey in osclass_entry
276- if vkey in _relevantkeys ] )
313+ for osmatch_entry in self .osmatches () :
314+ if osmatch_entry . accuracy >= min_accuracy :
315+ for oclass in osmatch_entry . osclasses :
316+ _ftstr = " type:{0}| vendor:{1}| osfamily{2}" . format (
317+ oclass . type ,
318+ oclass . vendor ,
319+ oclass . osfamily )
277320 os_array .append (_ftstr )
278- except (KeyError , TypeError ):
279- pass
280321 return os_array
281322
282323 def __repr__ (self ):
0 commit comments