root/branch/max/umitGUI/MainWindow.py @ 827

Revision 827, 30.7 kB (checked in by maxim-gavrilov, 6 years ago)

very old trunk sync

Line 
1# Copyright (C) 2005 Insecure.Com LLC.
2#
3# Authors: Adriano Monteiro Marques <py.adriano@gmail.com>
4#          Cleber Rodrigues <cleber.gnu@gmail.com>
5#                           <cleber@globalred.com.br>
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
21import gtk
22
23import sys
24import os
25import os.path
26
27from types import StringTypes
28from time import time
29from tempfile import mktemp
30
31from higwidgets.higwindows import HIGMainWindow
32from higwidgets.higdialogs import HIGDialog, HIGAlertDialog
33from higwidgets.higlabels import HIGEntryLabel
34from higwidgets.higboxes import HIGHBox, HIGVBox
35from higwidgets.hignotebooks import HIGAnimatedTabLabel
36
37from umitGUI.FileChoosers import ResultsFileChooserDialog, SaveResultsFileChooserDialog
38from umitGUI.ScanNotebook import ScanNotebook, ScanNotebookPage
39from umitGUI.ProfileEditor import ProfileEditor
40from umitGUI.Wizard import Wizard
41from umitGUI.About import About
42from umitGUI.DiffCompare import DiffWindow
43from umitGUI.SearchWindow import SearchWindow
44from umitGUI.BugReport import BugReport
45from umitGUI.ScriptManager import ScriptManagerWindow
46
47from umitCore.Paths import Path
48from umitCore.Logging import log
49from umitCore.I18N import _
50from umitCore.UmitConf import SearchConfig, is_maemo
51from umitCore.UmitDB import Scans, UmitDB
52
53root = False
54try:
55    if sys.platform == 'win32': root = True
56    elif is_maemo(): root = True
57    elif os.getuid() == 0: root = True
58except: pass
59
60
61UmitMainWindow = None
62hildon = None
63
64if is_maemo():
65    import hildon
66    class UmitMainWindow(hildon.Window):
67        def __init__(self):
68            hildon.Window.__init__(self)
69            self.set_resizable(False)
70            self.set_border_width(0)
71            self.vbox = gtk.VBox()
72            self.vbox.set_border_width(0)
73            self.vbox.set_spacing(0)
74
75else:
76    class UmitMainWindow(HIGMainWindow):
77        def __init__(self):
78            HIGMainWindow.__init__(self)
79            self.vbox = gtk.VBox()
80
81
82class MainWindow(UmitMainWindow):
83    def __init__(self):
84        UmitMainWindow.__init__(self)
85        self.set_title(_("Umit"))
86
87        self._icontheme = gtk.IconTheme()
88        self.main_accel_group = gtk.AccelGroup()
89       
90        self.add_accel_group(self.main_accel_group)
91       
92        self.add(self.vbox)
93       
94        self.connect ('delete-event', self._exit_cb)
95        self._create_ui_manager()
96        self._create_menubar()
97        self._create_toolbar()
98        self._create_scan_notebook()
99        self._verify_root()
100       
101        # These dialogs should be instanciated on demand
102        # Unfortunately, due to a GTK bug on the filefilters (or our own
103        # stupidity), we are creating/destroying them at each callback
104        # invocation. sigh.
105        self._profile_filechooser_dialog = None
106        self._results_filechooser_dialog = None
107       
108        self._new_scan_cb (None)
109
110    def configure_focus_chain(self):
111        self.vbox.set_focus_chain()
112
113    def _verify_root(self):
114        if not root:
115            non_root = NonRootWarning()
116
117    def _create_ui_manager(self):
118        self.ui_manager = gtk.UIManager()
119       
120        # See info on ActionGroup at:
121        # * http://www.pygtk.org/pygtk2reference/class-gtkactiongroup.html
122        # * http://www.gtk.org/api/2.6/gtk/GtkActionGroup.html
123        self.main_action_group = gtk.ActionGroup('MainActionGroup')
124       
125        # See info on Action at:
126        # * http://www.pygtk.org/pygtk2reference/class-gtkaction.html
127        # * http://www.gtk.org/api/2.6/gtk/GtkAction.html
128       
129        # Each action tuple can go from 1 to six fields, example:
130        # ('Open Scan Results',      -> Name of the action
131        #   gtk.STOCK_OPEN,          ->
132        #   _('_Open Scan Results'), ->
133        #   None,
134        #   _('Open the results of a previous scan'),
135        #   lambda x: True)
136       
137        about_icon = None
138        try: about_icon = gtk.STOCK_ABOUT
139        except: pass
140       
141        self.main_actions = [ \
142            # Top level
143            ('Scan', None, _('Sc_an'), None), 
144           
145            ('Wizard',
146                gtk.STOCK_CONVERT,
147                _('_Command Wizard'),
148                '<Control>i',
149                _('Open nmap command constructor wizard'),
150                self._wizard_cb),
151           
152            ('Save Scan',
153                gtk.STOCK_SAVE,
154                _('_Save Scan'),
155                None,
156                _('Save current scan results'),
157                self._save_scan_results_cb),
158           
159            ('Open Scan',
160                gtk.STOCK_OPEN,
161                _('_Open Scan'),
162                None,
163                _('Open the results of a previous scan'),
164                self._load_scan_results_cb),
165                   
166           
167            ('Tools', None, _('_Tools'), None), 
168           
169            ('New Scan',
170                gtk.STOCK_NEW,
171                _('_New Scan'),
172                "<Control>T",
173                _('Create a new Scan Tab'),
174                self._new_scan_cb),
175           
176            ('Close Scan',
177                gtk.STOCK_CLOSE,
178                _('Close Scan'),
179                "<Control>w",
180                _('Close current scan tab'),
181                self._close_scan_cb),
182           
183            ('New Profile',
184                gtk.STOCK_JUSTIFY_LEFT,
185                _('New _Profile'),
186                '<Control>p',
187                _('Create a new scan profile'),
188                self._new_scan_profile_cb),
189
190            ('Search Scan',
191                gtk.STOCK_FIND,
192                _('Search Scan Results'),
193                '<Control>f',
194                _('Search for a scan result'),
195                self._search_scan_result),
196           
197            ('Edit Profile',
198                gtk.STOCK_PROPERTIES,
199                _('_Edit Selected Profile'),
200                '<Control>e',
201                _('Edit selected scan profile'),
202                self._edit_scan_profile_cb),
203           
204            ('New Profile with Selected',
205                gtk.STOCK_PROPERTIES,
206                _('New P_rofile with Selected'),
207                '<Control>r',
208                _('Use the selected scan profile to create another'),
209                self._new_scan_profile_with_selected_cb),
210           
211            ('Quit',
212                gtk.STOCK_QUIT,
213                _('_Quit'),
214                None,
215            _('Quit this application'),
216                self._exit_cb),
217           
218           
219            # Top Level
220            ('Profile', None, _('_Profile'), None),
221           
222            ('Compare Results',
223                gtk.STOCK_DND_MULTIPLE,
224                _('Compare Results'),
225                "<Control>D",
226                _('Compare Scan Results using Diffies'),
227                self._load_diff_compare_cb),
228
229            ('Script Manager',
230                gtk.STOCK_INDEX,
231                _('Script Manager'),
232                "<Control>M",
233                _('Manage available scripts'),
234                self._load_script_manager_cb),
235           
236            # Top Level
237            ('Help', None, _('_Help'), None),
238
239            ('Report a bug',
240                gtk.STOCK_DIALOG_INFO,
241                _('_Report a bug'),
242                '<Control>b',
243                _("Report a bug"),
244                self._show_bug_report
245                ),
246           
247            ('About',
248                about_icon,
249                _('_About'),
250                '<Control>a',
251                _("About UMIT"),
252                self._show_about_cb
253                ),
254           
255            ('Show Help',
256                gtk.STOCK_HELP,
257                _('_Help'),
258                None,
259                _('Shows the application help'),
260                self._show_help),
261            ]
262       
263        # See info on UIManager at:
264        # * http://www.pygtk.org/pygtk2reference/class-gtkuimanager.html       
265        # * http://www.gtk.org/api/2.6/gtk/GtkUIManager.html
266       
267        # UIManager supports UI "merging" and "unmerging". So, suppose there's
268        # no scan running or scan results opened, we should have a minimal
269        # interface. When we one scan running, we should "merge" the scan UI.
270        # When we get multiple tabs opened, we might merge the tab UI.
271       
272        # This is the default, minimal UI
273        self.default_ui = """<menubar>
274        <menu action='Scan'>
275            <menuitem action='New Scan'/>
276            <menuitem action='Close Scan'/>
277            <menuitem action='Save Scan'/>
278            <menuitem action='Open Scan'/>
279             %s
280            <menuitem action='Quit'/>
281        </menu>
282
283        <menu action='Tools'>
284            <menuitem action='Wizard'/>
285            <menuitem action='Compare Results'/>
286            <menuitem action='Search Scan'/>
287            <menuitem action='Script Manager'/>
288         </menu>
289       
290        <menu action='Profile'>
291            <menuitem action='New Profile'/>
292            <menuitem action='New Profile with Selected'/>
293            <menuitem action='Edit Profile'/>
294        </menu>
295       
296        <menu action='Help'>
297            <menuitem action='Show Help'/>
298            <menuitem action='Report a bug'/>
299            <menuitem action='About'/>
300        </menu>
301       
302        </menubar>
303       
304        <toolbar>
305            <toolitem action='New Scan'/>
306            <toolitem action='Wizard'/>
307            <toolitem action='Save Scan'/>
308            <toolitem action='Open Scan'/>
309            <separator/>
310            <toolitem action='Report a bug'/>
311            <toolitem action='Show Help'/>
312        </toolbar>
313        """
314       
315        self.get_recent_scans()
316       
317        self.main_action_group.add_actions(self.main_actions)
318       
319        for action in self.main_action_group.list_actions():
320            action.set_accel_group(self.main_accel_group)
321            action.connect_accelerator()
322       
323        self.ui_manager.insert_action_group(self.main_action_group, 0)
324        self.ui_manager.add_ui_from_string(self.default_ui)
325
326    def _show_bug_report(self, widget):
327        bug = BugReport()
328        bug.show_all()
329
330    def _search_scan_result(self, widget):
331        search_window = SearchWindow(self._load_search_result)
332        search_window.show_all()
333
334    def _load_search_result(self, results):
335        for result in results:
336            page = self._load(parsed_result=results[result][1],
337                              title=results[result][1].scan_name)
338            page.status.set_search_loaded()
339
340    def _close_scan_cb(self, widget, data=None):
341        # data can be none, if the current page is to be closed
342        if data == None:
343            page_num = self.scan_notebook.get_current_page()
344        # but can also be this page's content, which will be used
345        # to find this page number
346        else:
347            page_num = self.scan_notebook.page_num(data)
348        page = self.scan_notebook.get_nth_page(page_num)
349        filename = None
350       
351        if page.status.unsaved_unchanged \
352               or page.status.unsaved_changed\
353               or page.status.loaded_changed:
354           
355            log.debug("Found changes on closing tab")
356            dialog = HIGDialog(buttons=(gtk.STOCK_SAVE, gtk.RESPONSE_OK,
357                            _('Close anyway'), gtk.RESPONSE_CLOSE,
358                            gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
359           
360            title = self.scan_notebook.get_tab_title(page)
361           
362            alert = None
363            if title:
364                alert = HIGEntryLabel('<b>%s "%s"</b>' % (_("Save changes on"), title))
365            else:
366                alert = HIGEntryLabel('<b>%s</b>' % _("Save changes"))
367           
368            text = HIGEntryLabel(_('The given scan has unsaved changes.\n\
369What do you want to do?'))
370            hbox = HIGHBox()
371            hbox.set_border_width(5)
372            hbox.set_spacing(12)
373           
374            vbox = HIGVBox()
375            vbox.set_border_width(5)
376            vbox.set_spacing(12)
377           
378            image = gtk.Image()
379            image.set_from_stock(gtk.STOCK_DIALOG_QUESTION,gtk.ICON_SIZE_DIALOG)
380           
381            vbox.pack_start(alert)
382            vbox.pack_start(text)
383            hbox.pack_start(image)
384            hbox.pack_start(vbox)
385           
386            dialog.vbox.pack_start(hbox)
387            dialog.vbox.show_all()
388           
389            response = dialog.run()
390            dialog.destroy()
391           
392            if response == gtk.RESPONSE_OK:
393                filename = self._save_scan_results_cb(page)
394                # filename = None means that user didn't saved the result
395            elif response == gtk.RESPONSE_CANCEL:
396                return False
397
398            self.store_result(page, filename)
399           
400        elif page.status.scanning:
401            log.debug("Trying to close a tab with a running scan")
402            dialog = HIGDialog(buttons=(_('Close anyway'), gtk.RESPONSE_CLOSE,
403                                        gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
404           
405            title = self.scan_notebook.get_tab_title(page)
406           
407            alert = None
408            if title:
409                alert = HIGEntryLabel('<b>%s "%s"</b>' % (_("Trying to close"), title))
410            else:
411                alert = HIGEntryLabel('<b>%s</b>' % _("Trying to close"))
412           
413            text = HIGEntryLabel(_('The page you are trying to close has a scan \
414running at the background.\nWhat do you want to do?'))
415            hbox = HIGHBox()
416            hbox.set_border_width(5)
417            hbox.set_spacing(12)
418           
419            vbox = HIGVBox()
420            vbox.set_border_width(5)
421            vbox.set_spacing(12)
422           
423            image = gtk.Image()
424            image.set_from_stock(gtk.STOCK_DIALOG_WARNING, gtk.ICON_SIZE_DIALOG)
425           
426            vbox.pack_start(alert)
427            vbox.pack_start(text)
428            hbox.pack_start(image)
429            hbox.pack_start(vbox)
430           
431            dialog.vbox.pack_start(hbox)
432            dialog.vbox.show_all()
433           
434            response = dialog.run()
435            dialog.destroy()
436           
437            if response == gtk.RESPONSE_CLOSE:
438                page.kill_scan()
439            elif response == gtk.RESPONSE_CANCEL:
440                return False
441        elif not page.status.empty:
442            alert = HIGAlertDialog(message_format=_('Closing current Scan Tab'),
443                                   secondary_text=_('Are you sure you want to close current \
444Scan Tab?'),
445                                   buttons=gtk.BUTTONS_OK_CANCEL,
446                                   type=gtk.MESSAGE_WARNING)
447            response = alert.run()
448            alert.destroy()
449
450            if response != gtk.RESPONSE_OK:
451                return False
452       
453        page.close_tab()
454        del(page)       
455        self.scan_notebook.remove_page(page_num)
456        return True
457
458    def store_result(self, page, filename):
459        page.parsed.scan_name = self.scan_notebook.get_tab_title(page)
460       
461        if not filename:
462            filename = mktemp()
463            f = open(filename, "w")
464            page.parsed.write_xml(f)
465            f.close()
466
467        search_config = SearchConfig()
468        if search_config.store_results:
469            try:
470                log.debug(">>> Saving result into data base...")
471                scan = Scans(scan_name=self.scan_notebook.get_tab_title(page),
472                             nmap_xml_output=open(filename).read(),
473                             date=time())
474            except:
475                log.debug("Error while trying to store result in Data Base!")
476
477
478
479    def get_recent_scans(self):
480        r_scans = []
481        new_rscan_xml = ''
482       
483        try:
484            recent = open(Path.recent_scans)
485            r_scans = recent.readlines()
486
487            recent.close()
488        except: pass
489       
490        for scan in r_scans[:7]:
491            scan = scan.replace('\n','')
492            #print '>>> Exists:', scan, os.path.isfile(scan)
493            if os.access(os.path.split(scan)[0],os.R_OK) and os.path.isfile(scan):
494               
495                scan = scan.replace('\n','')
496                new_rscan = (scan, None, scan, None, scan, self._load_recent_scan)
497                new_rscan_xml += "<menuitem action='%s'/>\n" % scan
498               
499                self.main_actions.append(new_rscan)
500        else:
501            new_rscan_xml += "<separator />\n"
502       
503        self.default_ui %= new_rscan_xml
504   
505    def _create_menubar(self):
506        # Get and pack the menubar
507        menubar = self.ui_manager.get_widget('/menubar')
508       
509        if is_maemo():
510            menu = gtk.Menu()
511            for child in menubar.get_children():
512                child.reparent(menu)
513            self.set_menu(menu)
514            menubar.destroy()
515            self.menubar = menu
516        else:
517            self.menubar = menubar
518            self.vbox.pack_start(self.menubar, False, False, 0)
519
520        self.menubar.show_all()
521
522    def _create_toolbar(self):
523        toolbar = self.ui_manager.get_widget('/toolbar')
524       
525        if is_maemo():
526            tb = gtk.Toolbar()
527            for child in toolbar.get_children():
528                child.reparent(tb)
529            self.add_toolbar(tb)
530            self.toolbar = tb
531            toolbar.destroy()
532        else:
533            self.toolbar = toolbar
534            self.vbox.pack_start(self.toolbar, False, False, 0)
535
536        self.toolbar.show_all()
537
538    def _create_scan_notebook(self):
539        self.scan_notebook = ScanNotebook()
540        self.scan_notebook.show_all()
541        if is_maemo():
542            # No padding. We need space!
543            self.vbox.pack_start(self.scan_notebook, True, True, 0)
544        else:
545            self.vbox.pack_start(self.scan_notebook, True, True, 4)
546
547    def _create_statusbar(self):
548        self.statusbar = gtk.Statusbar()
549        self.vbox.pack_start(self.statusbar, False, False, 0)
550
551    def _wizard_cb(self, widget):
552        w = Wizard()
553        w.set_notebook(self.scan_notebook)
554       
555        w.show_all()
556
557    def _load_scan_results_cb(self, p):
558        self._results_filechooser_dialog = ResultsFileChooserDialog(title=p.get_name())
559       
560        if (self._results_filechooser_dialog.run() == gtk.RESPONSE_OK):
561            self._load(filename=self._results_filechooser_dialog.get_filename())
562       
563        self._results_filechooser_dialog.destroy()
564        self._results_filechooser_dialog = None
565   
566    def _load_recent_scan(self, widget):
567        self._load(widget.get_name())
568
569    def _verify_page_usage(self, page):
570        """Verifies if given page is empty and can be used to load a result, or
571        if it's not empty and shouldn't be used to load a result. Returns True, if
572        it's ok to be used, and False if not.
573        """
574        if page == None \
575               or page.status.saved\
576               or page.status.unsaved_unchanged\
577               or page.status.unsaved_changed\
578               or page.status.loaded_unchanged\
579               or page.status.loaded_changed\
580               or page.status.parsing_result\
581               or page.status.scanning\
582               or page.status.search_loaded:
583            return False
584        else:
585            return True
586   
587    def _load(self, filename=None, parsed_result=None, title=None):
588        scan_page = None
589       
590        if filename or parsed_result:
591            current_page = self.scan_notebook.get_nth_page(self.scan_notebook.get_current_page())
592
593            if self._verify_page_usage(current_page):
594                log.debug(">>> Loading inside current scan page.")
595                scan_page = current_page
596            else:
597                log.debug(">>> Creating a new page to load it.")
598                scan_page = self._new_scan_cb(None)
599
600            log.debug(">>> Enabling page widgets")
601            scan_page.enable_widgets()
602
603        if filename and os.access(filename, os.R_OK):
604            # Load scan result from file
605            log.debug(">>> Loading file: %s" % filename)
606            log.debug(">>> Permissions to access file? %s" % os.access(filename, os.R_OK))
607
608            # Parse result
609            f = open(filename)
610            scan_page.parse_result(f)
611            scan_page.saved_filename = filename
612           
613            # Closing file to avoid problems with file descriptors
614            f.close()
615
616            log.debug(">>> Setting tab label")
617            self.scan_notebook.set_tab_title(scan_page, title)
618           
619        elif parsed_result:
620            # Load scan result from parsed object
621            scan_page.load_from_parsed_result(parsed_result)
622
623            log.debug(">>> Setting tab label")
624            self.scan_notebook.set_tab_title(scan_page, None)
625
626        elif filename and not os.access(filename, os.R_OK):
627            alert = HIGAlertDialog(message_format=_('Permission denied'),
628                                   secondary_text=_('Don\'t have read access to the path'))
629            alert.run()
630            alert.destroy()
631            return 
632        else:
633            alert = HIGAlertDialog(message_format=_('Could not load result'),
634                                   secondary_text=_('An unidentified error occouried and the \
635scan result was unable to be loaded properly.'))
636            alert.run()
637            alert.destroy()
638            return 
639
640        log.debug(">>> Setting flag that defines that there is no changes at \
641this scan result yet")
642        scan_page.changes = False
643        scan_page.status.set_loaded_unchanged()
644
645        log.debug(">>> Showing loaded result page")
646        self.scan_notebook.set_current_page(self.scan_notebook.get_n_pages()-1)
647        return scan_page
648   
649    def _save_scan_results_cb(self, saving_page):
650        current_page = self.scan_notebook.get_nth_page(self.scan_notebook.get_current_page())
651
652        try:
653            status = current_page.status
654        except:
655            alert = HIGAlertDialog(message_format=_('No scan tab'),
656                                   secondary_text=_('There is no scan tab or scan result \
657been shown. Run a scan and then try to save it.'))
658            alert.run()
659            alert.destroy()
660            return None
661
662
663        log.debug(">>> Page status: %s" % current_page.status.status)
664
665        if status.empty or status.unknown:    # EMPTY or UNKNOWN
666            # Show a dialog saying that there is nothing to be saved
667            alert = HIGAlertDialog(message_format=_('Nothing to save'),
668                                   secondary_text=_('No scan on this tab. Start a scan an \
669then try again'))
670            alert.run()
671            alert.destroy()
672
673        elif status.scan_failed:
674            alert = HIGAlertDialog(message_format=_('Nothing to save'),
675                                   secondary_text=_('The scan has failed! There is nothing \
676to be saved.'))
677            alert.run()
678            alert.destroy()
679
680        elif status.parsing_result:    # PARSING_RESULT
681            # Say that the result is been parsed
682            alert = HIGAlertDialog(message_format=_('Parsing the result'),
683                                   secondary_text=_('The result is still been parsed. \
684You can not save the result yet.'))
685            alert.run()
686            alert.destroy()
687
688        elif status.scanning:    # SCANNING
689            # Say that the scan is still running
690            alert = HIGAlertDialog(message_format=_('Scan is running'),
691                                   secondary_text=_('The scan process is not finished yet. \
692Wait until the scan is finished and then try to save it again.'))
693            alert.run()
694            alert.destroy()
695
696        elif status.unsaved_unchanged or status.unsaved_changed or status.search_loaded:
697            # UNSAVED_UNCHANGED and UNSAVED_CHANGED
698            # Show the dialog to choose the path to save scan result
699            self._save_results_filechooser_dialog = SaveResultsFileChooserDialog(\
700                                                                    title=_('Save Scan'))   
701            response = self._save_results_filechooser_dialog.run()
702
703            filename = None
704            if (response == gtk.RESPONSE_OK):
705                filename = self._save_results_filechooser_dialog.get_filename()
706                self._save(current_page, filename)
707               
708            self._save_results_filechooser_dialog.destroy()
709            self._save_results_filechooser_dialog = None
710
711            return filename
712
713        elif status.loaded_changed:    # LOADED_CHANGED
714            # Save the current result at the loaded file
715            self._save(current_page, current_page.saved_filename)
716        elif status.saved or status.loaded_unchanged:
717            pass
718        else:    # UNDEFINED status
719            alert = HIGAlertDialog(message_format=_('Nothing to save'),
720                                   secondary_text=_('No scan on this tab. Start a scan \
721 an then try again'))
722            alert.run()
723            alert.destroy()
724
725    def _show_about_cb(self, widget):
726        a = About()
727        a.show_all()
728   
729    def _save(self, saving_page, saved_filename):
730        log.debug(">>> File been saved: %s" % saved_filename)
731        if os.access(os.path.split(saved_filename)[0], os.W_OK):
732            f = None
733            try:
734                f = open(saved_filename, 'w')
735            except:
736                alert = HIGAlertDialog(message_format=_('Can\'t save file'),
737                            secondary_text=_('Can\'t open file to write'))
738                alert.run()
739                alert.destroy()
740            else:
741                saving_page.saved = True
742                saving_page.changes = False
743                saving_page.saved_filename = saved_filename
744                saving_page.collect_umit_info()
745
746                log.debug(">>> Page saved? %s" % saving_page.status.saved)
747                log.debug(">>> Changes on page? %s" % saving_page.status.status)
748                log.debug(">>> File to be saved at: %s" % saving_page.saved_filename)
749               
750                saving_page.parsed.write_xml(f)
751
752                # Closing file to avoid problems with file descriptors
753                f.close()
754
755                # Setting page status to saved
756                saving_page.status.set_saved()
757
758                # Saving recent scan information
759                rs = ['']
760                try:
761                    recent = open(Path.recent_scans)
762                    rs = recent.readlines()
763
764                    recent.close()
765                except:
766                    return None
767                else:
768                    rs.insert(0, saved_filename+'\n')
769
770                try:
771                    recent = open(Path.recent_scans,'w')
772                    recent.writelines(rs[:7])
773
774                    recent.close()
775                except:
776                    pass
777               
778        else:
779            alert = HIGAlertDialog(message_format=_('Permission denied'),
780                                   secondary_text=_('Don\'t have write access to this path.'))
781            alert.run()
782            alert.destroy()
783   
784    def _new_scan_cb(self, widget, data=None):
785        """Append a new ScanNotebookPage to ScanNotebook
786        New tab properties:
787        - Empty
788        - Disabled widgets
789        - Ready to start a new scan
790        - Untitled scan
791        """
792        page = ScanNotebookPage()
793        page.select_first_profile()
794       
795        self.scan_notebook.append_page(page, self._close_scan_cb, tab_title=data)
796        page.show_all()
797       
798        self.scan_notebook.set_current_page(-1)
799
800        # Put focus at the target combo, so user can open umit and start writing the target
801        page.target_focus()
802
803        return page
804
805    def _new_scan_profile_cb(self, p):
806        pe = ProfileEditor()
807        pe.set_notebook(self.scan_notebook)
808       
809        pe.show_all()
810   
811    def _edit_scan_profile_cb(self, p):
812        page = self.scan_notebook.get_nth_page\
813                (self.scan_notebook.get_current_page())
814        profile = page.toolbar.selected_profile
815       
816        pe = ProfileEditor(profile)
817        pe.set_notebook(self.scan_notebook)
818       
819        pe.show_all()
820   
821    def _new_scan_profile_with_selected_cb(self, p):
822        page = self.scan_notebook.get_nth_page(self.scan_notebook.get_current_page())
823        profile = page.toolbar.selected_profile
824       
825        pe = ProfileEditor(profile, delete=False)
826        pe.clean_profile_info()
827        pe.set_notebook(self.scan_notebook)
828       
829        pe.show_all()
830   
831    def _alert_with_action_name_cb(self, p):
832        d = HIGAlertDialog(parent=self,
833                           message_format=p.get_name(),
834                           secondary_text=_("The text above is this action's name"))
835        d.run()
836        d.destroy()
837
838    def _show_help(self, action):
839        import webbrowser
840        webbrowser.open("file://%s" % os.path.join(Path.docs_dir, "help.html"), new=2)
841
842    def _exit_cb (self, widget=None, extra=None):
843        for page in [self.scan_notebook.get_nth_page(n)\
844                     for n in xrange(self.scan_notebook.get_n_pages(), 0, -1)]:
845            if not self._close_scan_cb(page):
846                self.show_all()
847                return True
848        else:
849            # Cleaning up data base
850            UmitDB().cleanup(SearchConfig().converted_save_time)
851           
852            gtk.main_quit()
853
854    def _load_diff_compare_cb (self, widget=None, extra=None):
855        # We must change this test dict
856        # This dict has the following sintax:
857        # key = Scan name
858        # value = nmap output in string format
859        dic = {}
860       
861        for i in range(self.scan_notebook.get_n_pages()):
862            page = self.scan_notebook.get_nth_page(i)
863            scan_name = self.scan_notebook.get_tab_title(page)
864
865            if not scan_name:
866                scan_name = _("Scan ") + str(i+1)
867           
868            dic[scan_name] = page.parsed
869       
870        self.diff_window = DiffWindow(dic)
871       
872        self.diff_window.show_all()
873
874    def _load_script_manager_cb(self, widget = None, extra = None):
875        self.script_manager_window = ScriptManagerWindow()
876        self.script_manager_window.show_all()
877       
878class NonRootWarning (HIGAlertDialog):
879    def __init__(self):
880        warning_text = _('''You are trying to run UMIT with a non-root user!\n
881Some nmap options need root privileges to work.''')
882       
883        HIGAlertDialog.__init__(self, message_format=_('Non root user'),
884                                secondary_text=warning_text)
885
886        self.run()
887        self.destroy()
888
889
890if __name__ == '__main__':
891    w = MainWindow()
892    w.show_all()
893    gtk.main()
Note: See TracBrowser for help on using the browser.