root/branch/ggpolo/umitInventory/NewInventory.py @ 1384

Revision 1384, 17.9 kB (checked in by ggpolo, 6 years ago)

Added possiblity to run command wizard from inventory creation

Line 
1# Copyright (C) 2007 Insecure.Com LLC.
2#
3# Authors: Guilherme Polo <ggpolo@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
18# USA
19
20import os
21import gtk
22from ConfigParser import ConfigParser
23
24from umitCore.I18N import _
25from umitCore.Paths import Path
26from umitCore.UmitConf import CommandProfile
27
28from umitGUI.SchedulerEdit import SchedProfileEditor
29from umitGUI.ProfileCombo import ProfileCombo
30from umitGUI.Wizard import Wizard
31
32from umitInventory.HostDiscovery import HostDiscovery
33
34from higwidgets.higwindows import HIGWindow
35from higwidgets.higbuttons import HIGButton
36from higwidgets.higlabels import HIGEntryLabel
37from higwidgets.higboxes import HIGVBox, HIGHBox, hig_box_space_holder
38
39pixmaps_dir = Path.pixmaps_dir
40   
41if pixmaps_dir:
42    logo = os.path.join(pixmaps_dir, 'wizard_logo.png')
43else:
44    logo = None
45   
46class NewInventory(HIGWindow):
47    """
48    A window for creating new or editing existing Inventories.
49    """
50   
51    def __init__(self, inventory=None, edit_mode=False):
52        """
53        If you want to load an inventory at startup, pass it to inventory.
54        If you want to run this in edit mode, set to True edit_mode.
55        """
56        HIGWindow.__init__(self)
57
58        self.schemawin = None
59        self.discoverywin = None
60        self.edit_mode = edit_mode
61        if edit_mode:
62            self.wtitle = _("Editing Inventory")
63        else:
64            self.wtitle = _("New Inventory")
65           
66        # header
67        self.title_markup = "<span size='16500' weight='heavy'>%s</span>"
68        self.ttitle = HIGEntryLabel("")
69        self.ttitle.set_line_wrap(False)
70        self.ttitle.set_markup(self.title_markup % self.wtitle)
71        self.umit_logo = gtk.Image()
72        self.umit_logo.set_from_file(logo)
73        # inventory
74        self.invname_lbl = HIGEntryLabel(_("Inventory's name"))
75        self.invname = gtk.Entry()
76        self.invname.connect('changed', self._check_invname)
77        self.invname_inuse = HIGEntryLabel(_("in use"))
78        self.invname_inuse.set_sensitive(False)
79        self.invenabled = gtk.CheckButton(_("Enabled"))
80        self.invenabled.set_active(True)
81        # scan command
82        self.scandefault = gtk.CheckButton(_("Use default scan options"))
83        img_info = gtk.Image()
84        img_info.set_from_stock(gtk.STOCK_INFO, gtk.ICON_SIZE_MENU)
85        self.scandefault_tip = gtk.EventBox()
86        self.scandefault_tip.add(img_info)
87
88        self.scanadv = gtk.Expander(_("Use advanced scan options"))
89        self.scan_name_lbl = HIGEntryLabel(_("Scan Profile"))
90        self.scan_name = ProfileCombo()
91        self.scan_name.update()
92        self.scan_name.set_active(0)
93        self.scan_name.connect('changed', self._set_scan_command)
94        self.cmd_wizard = gtk.Button(stock=gtk.STOCK_CONVERT)
95        blbl = self.cmd_wizard.get_children()[0].get_children()[0].get_children()[1]
96        blbl.set_text(_("Command Wizard"))
97        self.cmd_wizard.connect('clicked', self._open_cmd_wizard)
98
99        self.scan_command_lbl = HIGEntryLabel(_("Command"))
100        self.scan_command = gtk.Entry()
101        self.scan_command.connect('changed', self._set_scan_type)
102        self._set_scan_command(None)
103        self.scandefault.set_active(True)
104        # scan target
105        self.scantarget_lbl = HIGEntryLabel(_("Scan target"))
106        self.scantarget = gtk.Entry()
107        self.scantarget_discovery = HIGButton(_("Use host discovery"))
108        self.scantarget_discovery.connect('clicked', self._open_host_discovery)
109        # scheduling profiles
110        self.sched_name_lbl = HIGEntryLabel(_("Scheduling Profile"))
111        self.sched_name = gtk.combo_box_new_text()
112        self.sched_name_edit = gtk.Button(stock=gtk.STOCK_EDIT)
113        blbl = self.sched_name_edit.get_children()[0].get_children()[0].get_children()[1]
114        blbl.set_text(_("Edit Profiles"))
115        self.sched_name_edit.connect('clicked', self._edit_schedprofiles)
116        # bottom buttons
117        self.help = HIGButton(stock=gtk.STOCK_HELP)
118        self.help.connect('clicked', self._show_help)
119        self.cancel = HIGButton(stock=gtk.STOCK_CANCEL)
120        self.cancel.connect('clicked', self._exit)
121        self.ok = HIGButton(stock=gtk.STOCK_OK)
122        self.ok.connect('clicked', self._save_inventory_and_leave)
123       
124        self.tooltips = gtk.Tooltips()
125        self.tooltips.set_tip(self.scandefault_tip, 
126                              _("nmap -T Aggressive -sV -n -O -v target"))
127       
128        # disable controls if edit_mode=True
129        if edit_mode:
130            self.invname.set_sensitive(False)
131            self.scandefault.set_sensitive(False)
132            self.scandefault_tip.set_sensitive(False)
133            self.scanadv.set_sensitive(False)
134            self.scan_name.set_sensitive(False)
135            self.scan_command.set_sensitive(False)
136            self.scantarget_lbl.set_sensitive(False)
137            self.scantarget.set_sensitive(False)
138            self.scantarget_discovery.set_sensitive(False)
139       
140        self.connect('destroy', self._exit)
141        self.profile_running = None # no SchedProfileEditor instance is running.
142        self.load_schemas()
143        self._load_pscheds() 
144
145        # load an inventory if especified
146        self.loaded_command = None
147        if inventory:
148            self.load_inventory(inventory)
149
150        self.__set_props()
151        self.__do_layout()
152
153   
154    def load_inventory(self, inventory):
155        """
156        Load inventory.
157        """
158        inv = ConfigParser()
159        inv.read(Path.sched_schemas)
160
161        self.invname.set_text(inventory)
162        for item in inv.items(inventory):
163            if item[0] == 'profile':
164                pindx = self.profiles.index(item[1])
165                self.sched_name.set_active(pindx)   
166            if item[0] == 'enabled':
167                self.invenabled.set_active(int(item[1]))
168            if item[0] == 'command':
169                self.loaded_command = item[1]
170
171   
172    def load_schemas(self):
173        """
174        Load scheduler schemas profiles.
175        """
176        schemas = ConfigParser()
177        schemas.read(Path.sched_schemas)
178       
179        self.sections = [ ]
180        for section in schemas.sections():
181            self.sections.append(section)
182       
183
184    def _load_pscheds(self):
185        """
186        Load scheduling profiles.
187        """
188        pscheds = ConfigParser()
189        pscheds.read(Path.sched_profiles)
190       
191        self.profiles = [ ]
192        self.sched_name.get_model().clear()
193        for section in pscheds.sections():
194            self.sched_name.append_text(section)
195            self.profiles.append(section)
196           
197        self.sched_name.set_active(0)
198       
199       
200    def _check_invname(self, event):
201        """
202        Check if Inventory's name isn't in use.
203        """
204        if self.invname.get_text() and \
205           (self.invname.get_text() in self.sections) and \
206            not self.edit_mode:
207            self.invname_inuse.set_sensitive(True)
208        else:
209            self.invname_inuse.set_sensitive(False)
210
211       
212    def _edit_schedprofiles(self, event):
213        """
214        Open Scheduling Profiles Editor.
215        """
216        if self.profile_running:
217            return
218       
219        win = SchedProfileEditor(self, self.sched_name.get_active_text())
220        win.show_all()
221        self.profile_running = win
222
223
224    def _set_scan_type(self, event):
225        """
226        When scan command is changed, unset "Default scan options" if it is
227        selected.
228        """
229        if self.scandefault.get_active():
230            self.scandefault.set_active(False)
231           
232
233    def _open_cmd_wizard(self, event):
234        """
235        Run command wizard window and update combobox when it finishes.
236        """
237        def update_scan_profiles(wwin):
238            self.scan_name.update()   
239
240        w = Wizard()
241        w.show_all()
242        w.connect('destroy', update_scan_profiles)
243
244
245    def _open_host_discovery(self, event):
246        """
247        Open host discovery window.
248        """
249        if self.discoverywin:
250            return
251       
252        w = HostDiscovery(self)
253        w.show_all()
254       
255        self.discoverywin = w
256
257
258    def get_discoverywin(self):
259        """
260        Get HostDiscovery running instance.
261        """
262        return self.__discoverywin
263   
264   
265    def set_discoverywin(self, win):
266        """
267        Set HostDiscovery instance.
268        """
269        self.__discoverywin = win
270       
271
272    def get_schemawin(self):
273        """
274        Get scheduelr schemas editor running instance.
275        """
276        return self.__schemawin
277
278   
279    def set_schemawin(self, win):
280        """
281        Set scheduler schemas editor instance.
282        """
283        self.__schemawin = win
284
285
286    def get_profile_running(self):
287        """
288        Get profile editor running instance.
289        """
290        return self.__profilerunning
291   
292   
293    def set_profile_running(self, running):
294        """
295        Set profile editor instance.
296        """
297        self.__profilerunning = running
298
299
300    def _save_inventory(self, event):
301        """
302        Save inventory.
303        """
304        target = self.scantarget.get_text()
305        invname = self.invname.get_text()
306        notinuse = (self.invname_inuse.state == gtk.STATE_INSENSITIVE)
307        command_adv = self.scan_command.get_text()
308
309        # checking for errors
310        if not notinuse or not len(invname) and not self.edit_mode:
311            dlg = HIGAlertDialog(self, 
312                                 message_format=_('New Inventory - Error\
313 while creating.'),
314                                 secondary_text=_("You tried to use an \
315existing Inventory name or you didn't specify one."))
316           
317            dlg.run()
318            dlg.destroy()
319            return 0
320       
321        if not len(target) and not self.edit_mode:
322            dlg = HIGAlertDialog(self, 
323                                 message_format=_('New Inventory - Error\
324 while creating.'),
325                                 secondary_text=_("You didn't specify any \
326target."))
327           
328            dlg.run()
329            dlg.destroy()
330            return 0
331       
332        if not len(command_adv) and not self.scandefault.get_active() \
333            and not self.edit_mode:
334            dlg = HIGAlertDialog(self, 
335                                 message_format=_('New Inventory - Error\
336 while creating.'),
337                                 secondary_text=_("You need to toggle \"Use \
338default scan options\" or specify a command."))
339           
340            dlg.run()
341            dlg.destroy()
342            return 0
343        # end error checking
344
345        if self.scandefault.get_active() and not self.edit_mode:
346            command = "nmap -T Aggressive -sV -n -O -v " + target
347        elif not self.edit_mode:
348            target_cmd = "<target>"
349            target_pos = command_adv.find(target_cmd)
350            if target_pos != -1:
351                start = target_pos
352                end = target_pos + len(target_cmd)
353                command = command_adv[:start] + target + command_adv[end:]
354            else:
355                dlg = HIGAlertDialog(self, 
356                                 message_format=_('New Inventory - Error\
357 while creating.'),
358                                 secondary_text=_("It seems you removed \
359<target> from the Scan command entry, you need to leave it somewhere there."))
360           
361                dlg.run()
362                dlg.destroy()
363                return 0
364
365        schedule = self.sched_name.get_active_text()
366        enabled = int(self.invenabled.get_active())
367        # write inventory to schema's file
368        s_cfg = ConfigParser()
369        s_cfg.read(Path.sched_schemas)
370       
371        if not s_cfg.has_section(invname):
372            new_sec = True
373            s_cfg.add_section(invname)
374        elif self.edit_mode:
375            new_sec = False
376        else:
377            print "How the hell did we get here?!"
378            print "Report as BUG"
379            return 0
380       
381        if new_sec:
382            s_cfg.set(invname, 'profile', schedule)
383            s_cfg.set(invname, 'command', command)
384            s_cfg.set(invname, 'enabled', enabled)
385            s_cfg.set(invname, 'addtoinv', '2')
386            s_cfg.set(invname, 'saveto', '')
387            s_cfg.set(invname, 'mailto', '')
388            s_cfg.set(invname, 'smtp', '')
389        else:
390            s_cfg.set(invname, 'profile', schedule)
391            s_cfg.set(invname, 'enabled', enabled)
392           
393        s_cfg.write(open(Path.sched_schemas, 'w'))
394       
395        self.load_schemas()
396
397        return 1
398
399
400    def _save_inventory_and_leave(self, event):
401        """
402        Save Inventory and close window.
403        """
404        close_win = self._save_inventory(None)
405        if close_win:
406            self._exit(None)
407       
408       
409    def _set_scan_command(self, event):
410        """
411        Set scan command based on chosen profile.
412        """
413        profile = self.scan_name.get_selected_profile()
414        cmd_profile = CommandProfile()
415        command = cmd_profile.get_command(profile)
416        self.scan_command.set_text(command % '<target>')
417       
418       
419    def _show_help(self, event):
420        """
421        Show help for creating a New Inventory.
422        """
423        pass
424   
425   
426    def _exit(self, event):
427        """
428        Close window.
429        """
430        if self.schemawin:
431            self.schemawin._exit(None)
432           
433        if self.profile_running:
434            self.profile_running._exit(None)
435           
436        self.destroy()
437       
438       
439    def __set_props(self):
440        """
441        Set window properties.
442        """
443        self.set_title(self.wtitle)
444       
445       
446    def __do_layout(self):
447        """
448        Layout widgets.
449        """
450        main_vbox = HIGVBox()
451        main_vbox.set_border_width(5)
452        main_vbox.set_spacing(12)
453        header_hbox = HIGHBox()
454        invname_hbox = HIGHBox()
455        scan_hbox = HIGHBox()
456        scanadv_hbox = HIGHBox()
457        scantarget_hbox = HIGHBox()
458        sched_box = HIGHBox()
459        btns_hbox = HIGHBox()
460       
461        # header
462        header_hbox._pack_expand_fill(self.ttitle)
463        header_hbox._pack_noexpand_nofill(self.umit_logo)
464        # inventory's name
465        invname_hbox._pack_noexpand_nofill(self.invname_lbl)
466        invname_hbox._pack_expand_fill(self.invname)
467        invname_hbox._pack_noexpand_nofill(self.invname_inuse)
468        invname_hbox._pack_noexpand_nofill(self.invenabled)
469        # scan command
470        scan_hbox._pack_noexpand_nofill(self.scandefault)
471        scan_hbox._pack_noexpand_nofill(self.scandefault_tip)
472        scanadv_hbox._pack_expand_fill(self.scanadv)
473       
474        adv_box = HIGVBox()
475        scanadv_align = gtk.Alignment(0.5, 0.5, 1, 1)
476        scanadv_align.set_padding(6, 0, 12, 0)
477        scanname_box = HIGHBox()
478        scanname_box._pack_noexpand_nofill(self.scan_name_lbl)
479        scanname_box._pack_expand_fill(self.scan_name)
480        scanname_box._pack_noexpand_nofill(self.cmd_wizard)
481        adv_box.add(scanname_box)
482        scancmd_box = HIGHBox()
483        scancmd_box._pack_noexpand_nofill(self.scan_command_lbl)
484        scancmd_box._pack_expand_fill(self.scan_command)
485        adv_box.add(scancmd_box)
486       
487        scanadv_align.add(adv_box)
488        self.scanadv.add(scanadv_align)
489        # scan target
490        scantarget_hbox._pack_noexpand_nofill(self.scantarget_lbl)
491        scantarget_hbox._pack_expand_fill(self.scantarget)
492        scantarget_hbox._pack_noexpand_nofill(self.scantarget_discovery)
493        # scheduling profiles
494        sched_box._pack_noexpand_nofill(self.sched_name_lbl)
495        sched_box._pack_expand_fill(self.sched_name)
496        sched_box._pack_noexpand_nofill(self.sched_name_edit)
497        # bottom buttons
498        btns_hbox.set_homogeneous(True)
499        btns_hbox._pack_expand_fill(self.help)
500        btns_hbox._pack_expand_fill(hig_box_space_holder())
501        btns_hbox._pack_expand_fill(self.cancel)
502        btns_hbox._pack_expand_fill(self.ok)
503       
504       
505        main_vbox._pack_noexpand_nofill(header_hbox)
506        main_vbox._pack_noexpand_nofill(gtk.HSeparator())
507        main_vbox._pack_noexpand_nofill(invname_hbox)
508        main_vbox._pack_noexpand_nofill(scan_hbox)
509        main_vbox._pack_noexpand_nofill(scanadv_hbox)
510        main_vbox._pack_noexpand_nofill(scantarget_hbox)
511
512        if self.loaded_command and self.edit_mode:
513            view_cmd_box = HIGHBox()
514            view_cmd_box._pack_noexpand_nofill(gtk.Label(_("Command")))
515            cmd_entry = gtk.Entry()
516            cmd_entry.set_text(self.loaded_command)
517            view_cmd_box._pack_expand_fill(cmd_entry)
518            img_info = gtk.Image()
519            img_info.set_from_stock(gtk.STOCK_INFO, gtk.ICON_SIZE_MENU)
520            eb = gtk.EventBox()
521            eb.add(img_info)
522            self.tooltips.set_tip(eb, _("Changes in command won't be saved!"))
523            view_cmd_box.pack_end(eb, False, False, 0)
524            main_vbox._pack_noexpand_nofill(view_cmd_box)
525       
526        main_vbox._pack_noexpand_nofill(sched_box)
527        main_vbox.pack_end(btns_hbox, False, False, 0)
528        main_vbox.pack_end(gtk.HSeparator(), False, False, 0)
529       
530        self.add(main_vbox)
531       
532   
533    # Properties
534    schemawin = property(get_schemawin, set_schemawin)
535    discoverywin = property(get_discoverywin, set_discoverywin)
536    profile_running = property(get_profile_running, set_profile_running)
537       
538
539if __name__ == "__main__":
540    w = NewInventory()
541    w.show_all()
542    w.connect('delete-event', lambda *args: gtk.main_quit())
543    gtk.main()
Note: See TracBrowser for help on using the browser.