root/trunk/umitGUI/radialnet/GraphBuilder.py @ 3927

Revision 3927, 13.6 kB (checked in by gpolo, 4 years ago)

* Fixes for the following tickets: 66, 99, 185, 186, 187, 188, 189, 194, 195

Merged revisions 3913,3917,3922,3924-3926 via svnmerge from
http://svn.umitproject.org/svnroot/umit/branch/NetworkInventory

........

r3913 | gpolo | 2009-01-06 23:15:56 -0200 (Tue, 06 Jan 2009) | 5 lines


  • Merged NmapParser? from the nmapparser branch;
  • Fixed several things in umitGUI to work with this updated parser which ended up fixing several other problems present in umit (note that there are many more things to fix -- probably).

........

r3917 | gpolo | 2009-01-07 10:29:46 -0200 (Wed, 07 Jan 2009) | 3 lines


  • More fixes -- some related to the new parser;
  • Updated parser to the latest version from its branch.

........

r3922 | gpolo | 2009-01-07 11:10:29 -0200 (Wed, 07 Jan 2009) | 1 line


Updated XMLStore to work with the new parser

........

r3924 | gpolo | 2009-01-07 11:24:48 -0200 (Wed, 07 Jan 2009) | 3 lines


  • More umitDB fixes to work with the new parser;
  • Merged latest NmapParser?.

........

r3925 | gpolo | 2009-01-07 11:52:22 -0200 (Wed, 07 Jan 2009) | 1 line


Updated DiffCompare? to use the new parser

........

r3926 | gpolo | 2009-01-07 12:10:12 -0200 (Wed, 07 Jan 2009) | 1 line


Updated SearchResult? to the new parser

........

Line 
1# -*- coding: utf-8 -*-
2# Copyright (C) 2008 Adriano Monteiro Marques.
3#
4# Author: João Paulo de Souza Medeiros <ignotus21@gmail.com>
5#         Luis A. Bastiao Silva <luis.kop@gmail.com>
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
21"""
22
23A GraphBuilder is a class that make a Graph across NmapParser
24
25"""
26
27from umitCore.radialnet.Graph import *
28from umitGUI.radialnet.RadialNet import NetNode
29
30
31COLORS = [(0.0, 1.0, 0.0),
32          (1.0, 1.0, 0.0),
33          (1.0, 0.0, 0.0)]
34
35BASE_RADIUS = 5.5
36NONE_RADIUS = 4.5
37
38
39
40class GraphBuilder(Graph):
41    def __init__(self):
42        Graph.__init__(self)
43       
44    def __set_default_values(self, node):
45           
46        node.set_info({'ip':'127.0.0.1/8', 'hostname':'localhost'})
47        node.set_draw_info({'color':(0,0,0), 'radius':NONE_RADIUS})
48       
49       
50    def __calc_vulnerability_level(self, node, host):
51        """
52        """
53        ports = host.ports
54        number_ports = len(host.ports)
55   
56        node.set_info({'number_of_scanned_ports': number_ports})
57   
58        if number_ports < 3:
59            node.set_info({'vulnerability_score': 0})
60   
61        elif number_ports < 7:
62            node.set_info({'vulnerability_score': 1})
63   
64        else:
65            node.set_info({'vulnerability_score': 2})
66   
67    def __set_node_info(self, node, host):
68        """
69        """
70        node.set_info({'host_reference': host})
71   
72        # getting vulnerability score
73        self.__calc_vulnerability_level(node, host)
74   
75        radius = BASE_RADIUS + node.get_info('number_of_scanned_ports') / 2
76        node.set_draw_info({'color':COLORS[\
77            node.get_info('vulnerability_score')],\
78                            'radius':radius})
79   
80        # getting address and hostnames
81        for addr in host.address:
82            if addr['addrtype'] == 'ipv4':
83                host_addresses = addr
84                break
85        else:
86            host_addresses = {}
87        if host_addresses.has_key('vendor') and host_addresses['vendor'] == '':
88            host_addresses['vendor'] = None
89
90        addresses = list()
91   
92        addresses.append(host_addresses)
93   
94        node.set_info({'addresses': addresses})
95        node.set_info({'ip': addresses[0]['addr']})
96   
97        host_hostnames = host.hostnames
98        if host_hostnames:
99            hostnames = list()
100            for host_hostname in host_hostnames:
101                hostnames.append(host_hostname.copy())
102
103            node.set_info({'hostnames': hostnames})
104            node.set_info({'hostname': hostnames[0]['name']})
105   
106        # getting uptime
107        #xml_uptime = host.search_children('uptime', True)
108        host_uptime = host.get_uptime()
109        if host_uptime != {}:
110            node.set_info({'uptime': host_uptime})
111   
112        # getting os fingerprint information
113   
114        os = {}
115
116        host_osfingerprint = host.osfingerprint
117        host_osclasses = host.osclass
118        host_osmatches = host.osmatch
119        host_portsused = host.portused
120        os['fingerprint'] = ""
121        if host_osfingerprint and host_osfingerprint[0].has_key('fingerprint'):
122            os['fingerprint'] = host_osfingerprint[0]['fingerprint']
123
124        if len(host_osclasses) > 0:
125
126            types = ['router', 'wap', 'switch', 'firewall']
127
128            for _type in types:
129                if _type in host_osclasses[0]['type'].lower():
130                    node.set_info({'device_type': _type})
131
132            os_classes = []
133
134            for host_osclass in host_osclasses:
135
136                os_class = {}
137
138                os_class['type'] = host_osclass['type']
139                os_class['vendor'] = host_osclass['vendor']
140                os_class['accuracy'] = int(host_osclass['accuracy'])
141                os_class['os_family'] = host_osclass['osfamily']
142
143                if host_osclass.has_key('osgen'):
144                    os_class['os_gen'] = host_osclass['osgen']
145
146                os_classes.append(os_class)
147
148            os['classes'] = os_classes
149        if len(host_osmatches) > 0:
150            os_matches = []
151
152            for host_osmatch in host_osmatches:
153
154                os_match = {}
155                os_match['name'] = host_osmatch['name']
156                if host_osmatch.get('accuracy', None):
157                    os_match['accuracy'] = int(host_osmatch['accuracy'])
158                # TODO/FIXME:
159                #os_match['db_line'] = int(host_osmatch['line'])
160                os_match['db_line'] = 0 
161                os_matches.append(os_match)
162
163            os['matches'] = os_matches
164        if len(host_portsused) > 0:
165
166            os_portsused = []
167
168            for host_portused in host_portsused:
169                host_portused['protocol'] = host_portused['proto']
170                host_portused['id'] = int(host_portused['portid'])
171                os_portsused.append(host_portused)
172
173            os['used_ports'] = os_portsused
174
175        node.set_info({'os': os})
176   
177        # getting (copies of) sequences information
178        host_tcpsequence = host.tcpsequence.copy()
179        host_ipidsequence = host.ipidsequence.copy()
180        host_tcptssequence = host.tcptssequence.copy()
181       
182        sequences = {}
183   
184        if host_tcpsequence:
185            if host_tcpsequence['index']:
186                host_tcpsequence['index'] = int(host_tcpsequence['index'])
187            host_tcpsequence['values'] = host_tcpsequence['values'].split(',')
188            sequences['tcp'] = host_tcpsequence
189   
190        if host_ipidsequence:
191            ip_id = host_ipidsequence
192            ip_id['values'] = host_ipidsequence['values'].split(',')
193   
194            sequences['ip_id'] = ip_id
195   
196        if host_tcptssequence:
197            if host_tcptssequence.get('values', None):
198                host_tcptssequence['values'] = \
199                        host_tcptssequence['values'].split(',')
200   
201            sequences['tcp_ts'] = host_tcptssequence
202
203        node.set_info({'sequences': sequences})
204   
205        # host is host filtered
206        filtered = False
207       
208        host_filtered = host.status['state']
209        if host_filtered=="filtered":
210            filtered=True
211       
212        ## Search in ports
213        filtered_ports = host.get_filtered_ports()
214       
215   
216        if filtered or filtered_ports > 0:
217            node.set_info({'filtered': True})
218   
219        # getting ports information
220
221        host_ports = host.ports
222        host_extraports = host.extraports
223        ports = []
224
225        for port in host_ports:
226            port = port.copy() # Do not change the original port
227            port['id'] = int(port['portid'])
228            # TODO: Not ready to integrate right now
229            #for script in xml_scripts:
230                #scripts.append(dict())
231                #for key in script.get_keys():
232                    #scripts[-1][key] = script.get_attr(key)
233
234            service = {}
235            # TODO: Get another information - NmapParser update need.
236            if 'name' in port:
237                service['name'] = port.pop('name')
238                service['version'] = port.pop('version', '')
239                service['method'] = port.pop('method', '')
240                service['product'] = port.pop('product', '')
241                service['extrainfo'] = port.pop('extrainfo', '')
242                service['conf'] = port.pop('conf', '')
243
244            port['state'] = {'state': port['state']}
245            port['scripts'] = {}
246            port['service'] = service
247
248            ports.append(port)
249
250        node.set_info({'ports':ports})
251
252        all_extraports = list()
253        #print host_extraports
254        for extraports in host_extraports:
255            extraports = extraports.copy() # Do not change the original eport
256            extraports['count'] = int(extraports['count'])
257            extraports['reason'] = list()
258            extraports['all_reason'] = list()
259   
260           
261            # TODO: implement this
262           
263            #xml_extrareasons = xml_extraport.search_children('extrareasons',
264                                                             #deep=True)
265   
266            #for extrareason in xml_extrareasons:
267   
268                #extraports['reason'].append(extrareason.get_attr('reason'))
269                #extraports['all_reason'].append(dict())
270           
271                #for key in extrareason.get_keys():
272   
273                    #value = extrareason.get_attr(key)
274   
275                    #if key == 'count':
276                        #value = int(value)
277   
278                    #extraports['all_reason'][-1][key] = value
279   
280            all_extraports.append(extraports)
281   
282        node.set_info({'extraports':all_extraports})
283   
284        # getting traceroute information
285        trace = host.trace
286        if trace and trace['hop']:
287   
288            host_hops = trace['hop']
289            hops = []
290   
291            for host_hop in host_hops:
292                hop = host_hop
293                hostname = host_hop.get('host', None)
294                hop['ttl'] = int(hop['ttl'])
295                hop['hostname'] = (hostname, '')[hostname == None]
296                if 'host' in hop:
297                    hop.pop('host')
298   
299                hops.append(hop)
300   
301            trace['hops'] = hops
302            trace['protocol'] = trace['proto']
303   
304            node.set_info({'trace':trace})
305
306       
307    def make(self, parse):
308        """
309        Make a Graph
310        """
311        #Get Hosts
312        hosts = parse.get_hosts()
313       
314        nodes = list()
315        index = 1
316       
317        # setting initial reference host
318        nodes.append(NetNode(0))
319        node = nodes[-1]
320
321        self.__set_default_values(node)
322       
323        # for each host in hosts just mount the graph
324        for host in hosts:
325            trace = host.trace
326            # if host has traceroute information mount graph
327            if trace and trace['hop']:
328               
329                prev_node = nodes[0]
330               
331                hops = trace['hop']
332                ttls = [int(hop['ttl']) for hop in hops]
333               
334                # getting nodes of host by ttl
335                for ttl in range(1, max(ttls) + 1):
336                    if ttl in ttls:
337   
338                        hop = host.get_hop_by_ttl(ttl)
339                        # FIXME: Protect if hop == None
340                        for node in nodes:
341                            if hop.has_key('ipaddr'):
342                                hop['ip'] = hop['ipaddr']
343                            if hop['ipaddr'] == node.get_info('ip'):
344                                break
345   
346                        else:
347   
348                            nodes.append(NetNode(index))
349                            node = nodes[-1]
350                            index += 1
351   
352                            node.set_draw_info({'valid':True})
353                            node.set_info({'ip':hop['ipaddr']})
354                            node.set_draw_info({'color':(1,1,1),
355                                                'radius':NONE_RADIUS})
356                            if hop.has_key('host') and hop['host'] != None:
357                                node.set_info(\
358                                    {'hostname':hop['host']})
359   
360                        rtt = hop['rtt']
361   
362                        if rtt != '--':
363                            self.set_connection(node, prev_node, float(rtt))
364   
365                        else:
366                            self.set_connection(node, prev_node)
367   
368                    else:
369   
370                        nodes.append(NetNode(index))
371                        node = nodes[-1]
372                        index += 1
373   
374                        node.set_draw_info({'valid':False})
375                        node.set_info({'ip':None, 'hostname':None})
376                        node.set_draw_info({'color':(1,1,1), \
377                                            'radius':NONE_RADIUS})
378   
379                        self.set_connection(node, prev_node)
380   
381                    prev_node = node                   
382           
383        # for each full scanned host
384        for host in hosts:
385   
386            for addr in host.address:
387                if addr['addrtype'] == 'ipv4':
388                    ip = addr
389                    break
390            else:
391                ip = {}
392            for node in nodes:
393                if ip.has_key('addr') and ip['addr'] == node.get_info('ip'):
394                    break
395   
396            else:
397   
398                nodes.append(NetNode(index))
399                node = nodes[-1]
400                index += 1
401   
402                node.set_draw_info({'no_route':True})
403   
404                self.set_connection(node, nodes[0])
405   
406            node.set_draw_info({'valid':True})
407            node.set_info({'scanned':True})
408            self.__set_node_info(node, host)
409   
410        self.set_nodes(nodes)
411        self.set_main_node_by_id(0)
412       
413
414# Test Develpment
415def main():
416    from umitCore.NmapParser import NmapParser
417    parser = NmapParser("../../umit-within-radialnet/RadialNet2/share/sample/nmap_example.xml")
418    #parser = NmapParser("RadialNet2/share/sample/no_trace.xml")
419    parser.parse()
420   
421    graph = GraphBuilder()
422    graph.make(parser)
423   
424
425if __name__=="__main__":
426    main()
427
428
429
Note: See TracBrowser for help on using the browser.