root/branch/k0p/umitInterfaceEditor/ProfileCore.py @ 1380

Revision 1380, 13.9 kB (checked in by kop-labs, 6 years ago)

One more integration with ProfileCore?

Line 
1# Copyright (C) 2007 Insecure.Com LLC.
2#
3# Author: Luis A. Bastiao Silva <luis.kop@gmail.com>
4#
5# This program is free software; you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 2 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program; if not, write to the Free Software
17# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19from types import StringTypes
20from xml.dom import minidom   
21#import xml.dom.ext
22# Testing at devel
23from os.path import split, join
24
25from umitCore.Paths import Path
26#Path.set_umit_conf(join(split(__file__)[0], 'config', 'umit.conf'))
27#END DEV TEST
28options = Path.options
29#from umitCore.NmapCommand import CommandConstructor
30from umitCore.NmapOptions import NmapOptions
31#from umitGUI.OptionBuilder import OptionBuilder
32
33
34'''
35ProfileCore manage all of the profile.xml
36- Supports the reading of options
37- Supports the writing ordenabled options and groups
38- Add/Remove a group
39- Add options for each group
40
41## Special info:
42- If delete a group all options on this group should be
43  deleted too.
44- A feauture that should be have it's delete a option
45  if it's deleted by options.xml
46- Solve all problems with options dependentions
47'''
48
49
50class ProfileOption(object):
51    '''
52    This class contains a option on Profile and Wizard
53    It is a bridge between ProfileCore and Profile (Editable Box)
54    '''
55    def __init__(self, type, label, option=None, arg_type=None , option_list=None ):
56        self._type = type
57        self._label = label
58        self._option = option
59        self._arg_type = arg_type
60        self._option_list = option_list
61        self._section = None
62        self._next_opt = None
63    def set_section(self, section):
64        self._section = section
65    def set_type(self, type):
66        self._type = type
67    def set_next_opt(self, opt):
68        self._next_opt= opt
69    def get_next_opt(self):
70        return self._next_opt
71    def get_type(self):
72        return self._type
73    def get_label(self):
74        return self._label
75    def get_option(self):
76        return self._option
77    def get_arg_type(self):
78        return self._arg_type
79    def get_option_list(self):
80        return self._option_list
81    def get_hint(self):
82        pass
83    def get_section(self):
84        return self._section
85   
86
87def option_to_profileoption(option):
88    '''
89    This is a simples method to create a new ProfileOption from
90    a new Option.
91    It's a very primitive and useful when you create a new option at
92    profile based on a option
93    WHEN USE: example when do drag-n-drop, and received a Option
94    as we working with Profile, it's need a ProfileOption
95    '''
96    from umitInterfaceEditor.OptionsCore import Option
97    o = option
98    o = Option()
99    result = ProfileOption('option_check', o.get_name(), o.get_name(),
100                           o.get_arg_type())
101    return result
102   
103
104
105
106
107class ProfileCore(object):
108    def __init__(self, xml_file):
109        '''
110        Open XML file
111        It should be inheritance of OptionBuilder But I don't need
112        a function that update command.
113        So I implement a new way of read elements like OptionBuilder
114        with support of write in XML
115       
116       
117        @param xml_file: String with a path of file
118        @type xml_file: str
119        '''
120       
121        xml_desc = open(xml_file)
122        self.xml_parse = minidom.parse(xml_desc)
123        xml_desc.close()
124        self.root_tag = "interface"
125        self.xml = self.xml_parse.getElementsByTagName(self.root_tag)[0]
126        self.options = NmapOptions(options)
127       
128        self.groups = self.__parse_groups()
129        self.section_names = self.__parse_section_names()
130        self.tabs = self.__parse_tabs()
131       
132    # Private API
133   
134    def __parse_section_names(self):
135        dic = {}
136        for group in self.groups:
137            grp = self.xml.getElementsByTagName(group)[0]
138            dic[group] = grp.getAttribute(u'label')
139        return dic
140   
141    def __parse_groups(self):
142        return [g_name.getAttribute(u'name') for g_name in \
143                  self.xml.getElementsByTagName(u'groups')[0].\
144                  getElementsByTagName(u'group')]
145
146    def __parse_tabs(self):
147        '''
148       
149        This part should be interact with BoxEditable of Items
150        '''
151       
152        #XXX fix OptionTab - implement new way
153        dic = {}
154        for tab_name in self.groups:
155            #dic[tab_name] = OptionTab(self.xml.getElementsByTagName(tab_name)[0],
156            #                          self.options, self.constructor, self.update_func)
157            dic[tab_name] = self.xml.getElementsByTagName(tab_name)[0]
158        return dic
159   
160       
161
162    #Public API
163    def get_group(self):
164       
165        for root_tab in self.tabs:
166            print root_tab
167            for option_element in self.tabs[root_tab].childNodes:
168                try:option_element.tagName
169                except:pass
170                else:
171                    print option_element.tagName
172                #self.widgets_list.append(actions[option_element.tagName](option_element, options_used))
173                #print ".."
174               
175    def get_section_node(self, section):
176        '''
177        get section node
178        '''
179               
180        element = self.xml.getElementsByTagName('groups')[0]
181        element_group = element.getElementsByTagName(u'group')
182        result = None 
183        for i in element_group:
184            result = i
185            if i.getAttribute('name') == section:
186                break
187           
188           
189        return result
190    def get_section(self, section):
191        '''
192        @param section: a section name
193        @type section: str
194        @return: a list of options
195        @rtype: a list of ProfileOption
196       
197        '''
198        result = []
199        for option in self.tabs[section].childNodes:
200            try: option.tagName
201            except:pass
202            else:
203                tagName = option.tagName
204                if tagName == 'option_check':
205                    tmp_po = ProfileOption(tagName, option.getAttribute(u'label'),
206                                           option.getAttribute(u'option'),
207                                           option.getAttribute(u'arg_type'),
208                                           None)
209                elif tagName == 'option_list':
210                   
211                    option_list = []
212                    for k in option.getElementsByTagName('option'):
213                        option_list.append(k.getAttribute(u'name'))
214                    tmp_po = ProfileOption(tagName, option.getAttribute(u'label'),
215                                           None, None, option_list)
216                                           
217                result.append(tmp_po)
218        return result
219
220       
221    def add_section(self):
222        pass
223    def remove_opt(self, section, name):
224       
225       
226        elem = self.search_option(section, name)
227        root = self.xml_parse.getElementsByTagName(self.root_tag)[0]
228        sec = root.getElementsByTagName(section)
229       
230        sec[0].removeChild(elem)
231    def remove_section(self, section_name):
232        '''
233        Removes section of the DOM
234        @param section_name: name of the section that will be removed
235        @type section_name: str
236        '''
237       
238       
239        root = self.xml_parse.getElementsByTagName(self.root_tag)[0]
240       
241        elem = self.search_in_groups(name)
242        root.removeChild(elem)
243       
244       
245       
246    def search_in_groups(self, name):
247        '''
248        Search a element of group
249        @param name: name of group to search
250        @type name: str
251       
252        @return : a Child None of DOM if found or None if not found
253        @rtype: ChildNode or None
254        '''
255       
256        element = self.xml.getElementsByTagName('groups')[0]
257        element_group = element.getElementsByTagName(u'group')
258        result = None 
259        for i in element_group:
260            if i.getAttribute('name') == name:
261                result = i
262        return result
263    def add_section_after(self, section, section_after):
264        pass
265   
266    def add_section_before(self, section, section_before):
267        '''
268        This function is to insert a new section at groups
269        with a new interface it is need insert and move sections
270       
271       
272        '''
273        #Fill element
274        element = self.xml_parse.createElementNS(None, "group")
275        element.setAttributeNS(None, 'name',section) 
276        #search Node to insert before it
277        beforeChild = self.search_in_groups(section_before)
278        #Add to xml doc
279        self.xml.getElementsByTagName('groups')[0].insertBefore(element,
280                                                                beforeChild )   
281   
282    def search_option(self, section_name, option_name):
283        '''
284        Search a option with a name and return this Node
285        @param section_name: A section name where is to looking for
286        @type section_name: str
287        @param option_name: A name of option for searching
288        @type option_name: str
289       
290        @return: A node with a element found or None if not found
291        @rtype: ChildNode element or None
292        '''
293       
294        grp = self.xml.getElementsByTagName(section_name)[0]
295        result = None 
296        for elem in grp.childNodes:
297            try: elem.getAttribute(u'label')
298            except: pass
299            else: 
300                if elem.getAttribute(u'label') == option_name:
301                    result = elem
302                    break 
303           
304        return result
305       
306    def add_option_before(self, section_name, option, before):
307
308        result = self.xml.getElementsByTagName(section_name)[0].insertBefore(option, before)       
309    def add_from_profileoption(self, profileoption):
310        '''
311        use add_option
312        '''
313        po = profileoption
314        section = po.get_section()
315        tagname = po.get_type()
316        label = po.get_label()
317        option = po.get_option()
318        arg_type = po.get_arg_type()
319        option_list = po.get_option_list()
320        option_name_next = po.get_next_opt()
321       
322       
323        self.add_option(section, tagname, label, option, arg_type, 
324                        option_list, option_name_next)
325       
326   
327    def add_option(self, section_name, tagname, label, option=None, 
328                   arg_type=None, options_list=None, option_name_before=None):
329        '''
330        Add a option in a section
331        - If is a optionlist it have a option_list and if the option
332        should be not inserted at the end of section have a option_name_before
333        @param section_name: A section name where options should be added
334        @type section_name: str
335        @param tagname: option_check, option_list or others used at
336        Profile Editor or Wizard
337        @type tagname: str
338        @param label: Name of this option
339        @type label: str
340        @param option: The option is used to link with file options.xml
341        @type option:  str
342        @param arg_type: type of arg (#XXX I think that it's obsulete right now)
343        @type arg_type:str
344        @param option_list: A list with a name options to option_list
345        @type option_list: list
346        @param option_name_before: name of option after where is inserted
347        @type option_name_before: str
348        '''
349        element = self.xml_parse.createElementNS(None, tagname)
350        if arg_type != None: 
351            element.setAttribute('arg_type', arg_type)
352        element.setAttribute('label',label)
353        if option != None:
354            element.setAttribute('option', option)
355        elements = [] 
356        if options_list != None: 
357           
358            for i in options_list:
359                element_in = self.xml_parse.createElementNS(None, 'option')
360                element_in.setAttributeNS(None, 'name', i)
361                elements.append(element_in)
362        after = None 
363        if option_name_before != None:
364            after = self.search_option(section_name, option_name_before)
365       
366        result = self.xml.getElementsByTagName(section_name)[0].insertBefore(element, after)       
367        if elements != [] :
368            for i in elements:
369                result.appendChild(i)
370   
371    def _determine_prev(self,section, list):
372        result = None 
373        for i in list:
374            if i.getAttribute('name') == section:
375                break
376           
377            result = i
378        return result
379   
380    def get_prev(self, section): 
381        '''
382        get prev section
383        '''
384               
385        element = self.get_group_element()
386        element_group = element.getElementsByTagName(u'group')
387        result = self._determine_prev(section, element_group)
388        return result
389    def get_next(self, section): 
390        '''
391        get next section
392        '''
393               
394        element = self.get_group_element()
395        element_group = element.getElementsByTagName(u'group')
396        element_group.reverse()
397        result = self._determine_prev(section, element_group)
398        return result
399
400
401    def get_group_element(self):
402        element = self.xml.getElementsByTagName('groups')[0]
403        return element
404    def move_section_left(self, section):
405        node_prev = self.get_prev(section)
406        node = self.get_section_node(section)
407        element = self.get_group_element()
408        element.removeChild(node)
409        element.insertBefore(node, node_prev)
410
411       
412    def move_section_right(self, section):
413        node_next = self.get_next(section)
414        node = self.get_section_node(section)
415        element = self.get_group_element()
416        element.removeChild(node_next)
417        element.insertBefore(node_next, node)
418       
419
420    def get_list_opt(self, section, label):
421        '''
422        Based on label of OptionList
423        return a List with a Options in.
424        '''
425        elem = self.search_option(section, label)
426        list = elem.getElementsByTagName(u'option')
427        result = [] 
428        for i in list:
429            name = i.getAttribute(u'name')
430            result.append(name)
431        return result
432    def get_prev_opt(section, option):
433        #XXX <- May be lack in other side
434        elem = self.search_option(section, option)
435        pass
436
437    def move_option_up(self, section,option, option_up):
438        option_prev =  self.search_option(section, option_up)
439        if option_up == None : 
440            pass
441        else: 
442            elem = self.search_option(section, option)
443            self.remove_opt(section, option)
444            self.add_option_before(section, elem, option_prev)
445
446           
447       
448    def move_option_down(self, section, option, option_down):
449        option_next =  self.search_option(section, option_down)
450        if option_down == None : 
451            pass
452        else: 
453            self.remove_opt(section, option_down)
454            elem = self.search_option(section, option)
455            self.add_option_before(section, option_next, elem)
456           
457
458   
459   
460    def print_screen(self):
461        xml.dom.ext.PrettyPrint(self.xml)
462    def write_file(self,filename):
463        '''
464        Write Option List to XML file
465        @param filename: File name of xml
466        @type filename: String
467        '''
468       
469        file_object = open(filename, "w")
470       
471        #xml.dom.ext.PrettyPrint(self.xml, file_object)
472        self.xml.writexml(file_object)
473        file_object.close()
474
475       
476       
477# This is only for test a implementation of ProfileCore
478
479def main():
480    s = ProfileCore("/home/kop/.umit/profile_editor.xml")
481    #for group in s.groups:
482        #print group
483    #for sections in s.section_names:
484        #print sections
485    #for tab in s.tabs:
486        #print tab
487    #s.get_group()
488    s.get_section('Scan')
489    #s.add_section_before('New label','Ping')
490    #s.add_option('Scan', 'option_list', 'dasdas', 'dasda',
491    #            'dasdas', ['sdas','dasda'], 'Timing: ')
492    s.remove_opt('Scan', 'TCP scan: ')
493    s.print_screen()
494   
495   
496
497if __name__ == "__main__":
498    main() 
499   
Note: See TracBrowser for help on using the browser.