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

Revision 1383, 17.2 kB (checked in by ggpolo, 6 years ago)

more minor changes

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