def __create_widgets(self): self.property_name_label = HIGEntryLabel("") self.example_label = HIGEntryLabel("") self.bold_tg_button = HIGToggleButton("", gtk.STOCK_BOLD) self.italic_tg_button = HIGToggleButton("", gtk.STOCK_ITALIC) self.underline_tg_button = HIGToggleButton("", gtk.STOCK_UNDERLINE) self.text_color_button = HIGButton(_("Text"), stock=gtk.STOCK_SELECT_COLOR) self.highlight_color_button = HIGButton(_("Highlight"), stock=gtk.STOCK_SELECT_COLOR)
def __create_widgets(self): ### # Vertical box to keep 3 boxes self.main_whole_box = HIGVBox() self.upper_box = HIGHBox() self.middle_box = HIGHBox() self.lower_box = HIGHBox() #self.main_vbox = HIGVBox() self.command_entry = gtk.Entry() self.command_entry_changed_cb_id = self.command_entry.connect( "changed", self.command_entry_changed_cb) self.scan_button = HIGButton(_("Scan")) self.scan_button.connect("clicked", self.run_scan) self.notebook = gtk.Notebook() # Profile info page self.profile_info_vbox = HIGVBox() self.profile_info_label = HIGSectionLabel(_('Profile Information')) self.profile_name_label = HIGEntryLabel(_('Profile name')) self.profile_name_entry = gtk.Entry() self.profile_name_entry.connect( 'enter-notify-event', self.update_help_name) self.profile_description_label = HIGEntryLabel(_('Description')) self.profile_description_scroll = HIGScrolledWindow() self.profile_description_scroll.set_border_width(0) self.profile_description_text = HIGTextView() self.profile_description_text.connect( 'motion-notify-event', self.update_help_desc) # Buttons self.buttons_hbox = HIGHBox() self.cancel_button = HIGButton(stock=gtk.STOCK_CANCEL) self.cancel_button.connect('clicked', self.exit) self.delete_button = HIGButton(stock=gtk.STOCK_DELETE) self.delete_button.connect('clicked', self.delete_profile) self.save_button = HIGButton(_("Save Changes"), stock=gtk.STOCK_SAVE) self.save_button.connect('clicked', self.save_profile) ### self.help_vbox = HIGVBox() self.help_label = HIGSectionLabel(_('Help')) self.help_scroll = HIGScrolledWindow() self.help_scroll.set_border_width(0) self.help_field = HIGTextView() self.help_field.set_cursor_visible(False) self.help_field.set_left_margin(5) self.help_field.set_editable(False) self.help_vbox.set_size_request(200, -1)
def __init__(self, param=""): HIGHBox.__init__(self) self.entry = OptionEntry() self.button = HIGButton(stock=gtk.STOCK_OPEN) self._pack_expand_fill(self.entry) self._pack_noexpand_nofill(self.button) self.entry.set_text(param) self.button.connect('clicked', self.open_dialog_cb)
def _create_widgets(self): self.vbox = HIGVBox() self.bottom_hbox = gtk.HBox() self.bottom_label = gtk.Label() self.btn_box = gtk.HButtonBox() self.btn_open = HIGButton(stock=gtk.STOCK_OPEN) self.btn_append = HIGButton(_("Append"), gtk.STOCK_ADD) self.btn_close = HIGButton(stock=gtk.STOCK_CLOSE) self.search_gui = SearchGUI(self)
def _create_widgets(self): self.date_criterion_combo = gtk.combo_box_new_text() self.date_criterion_combo.append_text("is") self.date_criterion_combo.append_text("after") self.date_criterion_combo.append_text("before") if self.operator == "date": self.date_criterion_combo.set_active(0) elif self.operator == "after": self.date_criterion_combo.set_active(1) else: self.date_criterion_combo.set_active(2) self.date_button = HIGButton()
def __init__(self, scans_store): HIGVBox.__init__(self) self.set_spacing(4) scans_store.connect("row-changed", self._row_changed) self.scans_list = gtk.TreeView(scans_store) self.scans_list.get_selection().connect("changed", self._selection_changed) status_col = gtk.TreeViewColumn(_("Status")) cell = gtk.CellRendererText() status_col.pack_start(cell) status_col.set_cell_data_func(cell, status_data_func) self.scans_list.append_column(status_col) command_col = gtk.TreeViewColumn(_("Command")) cell = gtk.CellRendererText() command_col.pack_start(cell) command_col.set_cell_data_func(cell, command_data_func) self.scans_list.append_column(command_col) scrolled_window = HIGScrolledWindow() scrolled_window.set_border_width(0) scrolled_window.add(self.scans_list) self.pack_start(scrolled_window, True, True) hbox = HIGHBox() buttonbox = gtk.HButtonBox() buttonbox.set_layout(gtk.BUTTONBOX_START) buttonbox.set_spacing(4) self.append_button = HIGButton(_("Append Scan"), gtk.STOCK_ADD) buttonbox.pack_start(self.append_button, False) self.remove_button = HIGButton(_("Remove Scan"), gtk.STOCK_REMOVE) buttonbox.pack_start(self.remove_button, False) self.cancel_button = HIGButton(_("Cancel Scan"), gtk.STOCK_CANCEL) buttonbox.pack_start(self.cancel_button, False) hbox.pack_start(buttonbox, padding=4) self.pack_start(hbox, False, padding=4) self._update()
def __init__(self, scans_store): HIGVBox.__init__(self) self.set_spacing(4) scans_store.connect("row-changed", self._row_changed) self.scans_list = gtk.TreeView(scans_store) self.scans_list.get_selection().connect( "changed", self._selection_changed) status_col = gtk.TreeViewColumn(_("Status")) cell = gtk.CellRendererText() status_col.pack_start(cell) status_col.set_cell_data_func(cell, status_data_func) self.scans_list.append_column(status_col) command_col = gtk.TreeViewColumn(_("Command")) cell = gtk.CellRendererText() command_col.pack_start(cell) command_col.set_cell_data_func(cell, command_data_func) self.scans_list.append_column(command_col) scrolled_window = HIGScrolledWindow() scrolled_window.set_border_width(0) scrolled_window.add(self.scans_list) self.pack_start(scrolled_window, True, True) hbox = HIGHBox() buttonbox = gtk.HButtonBox() buttonbox.set_layout(gtk.BUTTONBOX_START) buttonbox.set_spacing(4) self.append_button = HIGButton(_("Append Scan"), gtk.STOCK_ADD) buttonbox.pack_start(self.append_button, False) self.remove_button = HIGButton(_("Remove Scan"), gtk.STOCK_REMOVE) buttonbox.pack_start(self.remove_button, False) self.cancel_button = HIGButton(_("Cancel Scan"), gtk.STOCK_CANCEL) buttonbox.pack_start(self.cancel_button, False) hbox.pack_start(buttonbox, padding=4) self.pack_start(hbox, False, padding=4) self._update()
def __init__(self, scans): gtk.Window.__init__(self) self.set_title(_("Compare Results")) self.ndiff_process = None # We allow the user to start a new diff before the old one has # finished. We have to keep references to old processes until they # finish to avoid problems when tearing down the Python interpreter at # program exit. self.old_processes = [] self.timer_id = None self.main_vbox = HIGVBox() self.diff_view = DiffView() self.diff_view.set_size_request(-1, 100) self.hbox_buttons = HIGHBox() self.progress = gtk.ProgressBar() self.btn_close = HIGButton(stock=gtk.STOCK_CLOSE) self.hbox_selection = HIGHBox() self.scan_chooser_a = ScanChooser(scans, _(u"A Scan")) self.scan_chooser_b = ScanChooser(scans, _(u"B Scan")) self._pack_widgets() self._connect_widgets() self.set_default_size(-1, 500) # Initial Size Request self.initial_size = self.get_size()
def __create_widgets(self): ### # Vertical box to keep 3 boxes self.main_whole_box = HIGVBox() self.upper_box = HIGVBox() self.middle_box = HIGHBox() self.lower_box = HIGHBox() #self.main_vbox = HIGVBox() self.command_expander = HIGExpander('<b>' + _('Command') + '</b>') self.command_expander.set_expanded(True) self.command_entry = gtk.Entry() self.command_entry.set_editable(False) self.notebook = gtk.Notebook() # Profile info page self.profile_info_vbox = HIGVBox() self.profile_info_label = HIGSectionLabel(_('Profile Information')) self.profile_name_label = HIGEntryLabel(_('Profile name')) self.profile_name_entry = gtk.Entry() self.profile_name_entry.connect('enter-notify-event', self.update_help_name) self.profile_description_label = HIGEntryLabel(_('Description')) self.profile_description_scroll = HIGScrolledWindow() self.profile_description_scroll.set_border_width(0) self.profile_description_text = HIGTextView() self.profile_description_text.connect('motion-notify-event', self.update_help_desc) # Buttons self.buttons_hbox = HIGHBox() self.help_button = HIGButton(stock=gtk.STOCK_HELP) self.help_button.connect('clicked', self.help) self.cancel_button = HIGButton(stock=gtk.STOCK_CANCEL) self.cancel_button.connect('clicked', self.exit) self.delete_button = HIGButton(stock=gtk.STOCK_DELETE) self.delete_button.connect('clicked', self.delete_profile) self.ok_button = HIGButton(stock=gtk.STOCK_OK) self.ok_button.connect('clicked', self.save_profile) ### self.help_vbox = HIGVBox() self.help_label = HIGSectionLabel(_('Help')) self.help_scroll = HIGScrolledWindow() self.help_scroll.set_border_width(0) self.help_field = HIGTextView() self.help_field.set_cursor_visible(False) self.help_field.set_left_margin(5) self.help_field.set_editable(False) self.help_vbox.set_size_request(200, -1)
def __init__(self, option, ops, check): gtk.HBox.__init__(self) self.option = option self.ops = ops self.check = check self.entry = gtk.Entry() self.pack_start(self.entry, True, True) button = HIGButton(stock=gtk.STOCK_OPEN) self.pack_start(button, False) button.connect("clicked", self.clicked_cb) self.entry.connect("changed", lambda x: self.emit("changed")) self.entry.connect("changed", self.changed_cb) self.check.connect("toggled", self.check_toggled_cb) self.update()
def _create_widgets(self): self.main_vbox = HIGVBox() self.diff_view = DiffView() self.diff_view.set_size_request(-1, 100) self.hbox_buttons = HIGHBox() self.progress = gtk.ProgressBar() self.btn_close = HIGButton(stock=gtk.STOCK_CLOSE) self.hbox_selection = HIGHBox() self.scan_chooser_a = ScanChooser(self.scans, _(u"A Scan")) self.scan_chooser_b = ScanChooser(self.scans, _(u"B Scan"))
def _create_widgets(self): # Search box and buttons self.search_top_hbox = HIGHBox() self.search_label = HIGSectionLabel(_("Search:")) self.search_entry = gtk.Entry() self.expressions_btn = HIGToggleButton(_("Expressions "), gtk.STOCK_EDIT) # The quick reference tooltip button self.search_tooltip_btn = HIGButton(" ", gtk.STOCK_INFO) # The expression VBox. This is only visible once the user clicks on "Expressions" self.expr_vbox = gtk.VBox() # Results section self.result_list = gtk.ListStore(str, str, int) # title, date, id self.result_view = gtk.TreeView(self.result_list) self.result_scrolled = gtk.ScrolledWindow() self.result_title_column = gtk.TreeViewColumn(_("Scan")) self.result_date_column = gtk.TreeViewColumn(_("Date")) self.expr_window = None
def __create_widgets(self): self.vbox = HIGVBox() self.hbox = HIGHBox() self.notebook = HIGNotebook() self.btn_close = HIGButton(stock=gtk.STOCK_CLOSE) self.written_by_scroll = HIGScrolledWindow() self.written_by_text = HIGTextView() self.design_scroll = HIGScrolledWindow() self.design_text = HIGTextView() self.soc2007_scroll = HIGScrolledWindow() self.soc2007_text = HIGTextView() self.contributors_scroll = HIGScrolledWindow() self.contributors_text = HIGTextView() self.translation_scroll = HIGScrolledWindow() self.translation_text = HIGTextView() self.nokia_scroll = HIGScrolledWindow() self.nokia_text = HIGTextView()
class DirSubcriterion(Subcriterion): def __init__(self, operator="dir", argument=""): Subcriterion.__init__(self) self.operator = operator self.argument = argument self._create_widgets() self._pack_widgets() self._connect_widgets() def _create_widgets(self): self.dir_entry = gtk.Entry() if self.argument: self.dir_entry.set_text(self.argument) self.chooser_btn = HIGButton("Choose...", gtk.STOCK_OPEN) def _pack_widgets(self): self.pack_start(self.dir_entry, True) self.pack_start(self.chooser_btn, False) def _connect_widgets(self): self.chooser_btn.connect("clicked", self.choose_clicked) self.dir_entry.connect("changed", self.dir_entry_changed) def choose_clicked(self, widget=None, extra=None): # Display a directory chooser dialog chooser_dlg = DirectoryChooserDialog("Include folder in search") if chooser_dlg.run() == gtk.RESPONSE_OK: self.dir_entry.set_text(chooser_dlg.get_filename()) chooser_dlg.destroy() def dir_entry_changed(self, widget=None, extra=None): self.argument = widget.get_text() self.value_changed()
def _create_widgets(self): # A ComboBox containing the list of operators self.operator_combo = gtk.combo_box_new_text() # Sort all the keys from combo_entries and make an entry for each of them sorted_entries = self.combo_entries.keys() sorted_entries.sort() for name in sorted_entries: self.operator_combo.append_text(name) # Select the default operator for entry, operators in self.combo_entries.iteritems(): for operator in operators: if operator == self.default_operator: self.operator_combo.set_active(sorted_entries.index(entry)) break # Create a subcriterion self.subcriterion = self.new_subcriterion(self.default_operator, self.default_argument) # The "add" and "remove" buttons self.add_btn = HIGButton(" ", gtk.STOCK_ADD) self.remove_btn = HIGButton(" ", gtk.STOCK_REMOVE)
def _create_widgets(self): self.main_vbox = HIGVBox() self.hbox_mode = HIGHBox() self.hbox_settings = HIGHBox() self.hbox_buttons = HIGHBox() self.hbox_result = HIGHBox() self.btn_open_browser = HIGButton(_("Open in Browser"), stock=gtk.STOCK_EXECUTE) self.btn_help = HIGButton(stock=gtk.STOCK_HELP) self.btn_close = HIGButton(stock=gtk.STOCK_CLOSE) self.check_color = gtk.CheckButton(_("Enable colored diffies")) self.btn_legend = HIGButton(_("Color Descriptions"), stock=gtk.STOCK_SELECT_COLOR) self.text_mode = gtk.ToggleButton(_("Text Mode")) self.compare_mode = gtk.ToggleButton(_("Compare Mode")) self.vpaned = gtk.VPaned() self.hpaned = gtk.HPaned() self.scan_chooser1 = ScanChooser(self.scans, "1") self.scan_chooser2 = ScanChooser(self.scans, "2") self.scan_buffer1 = self.scan_chooser1.get_buffer() self.scan_buffer2 = self.scan_chooser2.get_buffer()
class HighlightProperty(object): def __init__(self, property_name, property): self.__create_widgets() self.property_name = property_name self.property_label = property[0].capitalize() self.example = property[1] self.bold = property[2] self.italic = property[3] self.underline = property[4] self.text_color = property[5] self.highlight_color = property[6] self.__connect_buttons() def __create_widgets(self): self.property_name_label = HIGEntryLabel("") self.example_label = HIGEntryLabel("") self.bold_tg_button = HIGToggleButton("", gtk.STOCK_BOLD) self.italic_tg_button = HIGToggleButton("", gtk.STOCK_ITALIC) self.underline_tg_button = HIGToggleButton("", gtk.STOCK_UNDERLINE) self.text_color_button = HIGButton(_("Text"), stock=gtk.STOCK_SELECT_COLOR) self.highlight_color_button = HIGButton(_("Highlight"), stock=gtk.STOCK_SELECT_COLOR) def __connect_buttons(self): self.bold_tg_button.connect("toggled", self.update_example) self.italic_tg_button.connect("toggled", self.update_example) self.underline_tg_button.connect("toggled", self.update_example) self.text_color_button.connect("clicked", self.text_color_dialog) self.highlight_color_button.connect("clicked", self.highlight_color_dialog) #################################### # Text color dialog def text_color_dialog(self, widget): color_dialog = gtk.ColorSelectionDialog("%s %s" % (self.label, _("text color"))) color_dialog.colorsel.set_current_color(self.text_color) color_dialog.ok_button.connect("clicked", self.text_color_dialog_ok, color_dialog) color_dialog.cancel_button.connect("clicked", self.text_color_dialog_cancel, color_dialog) color_dialog.connect("delete-event", self.text_color_dialog_close, color_dialog) color_dialog.run() def text_color_dialog_ok(self, widget, color_dialog): self.text_color = color_dialog.colorsel.get_current_color() color_dialog.destroy() self.update_example() def text_color_dialog_cancel(self, widget, color_dialog): color_dialog.destroy() def text_color_dialog_close(self, widget, extra, color_dialog): color_dialog.destroy() ######################################### # Highlight color dialog def highlight_color_dialog(self, widget): color_dialog = gtk.ColorSelectionDialog( "%s %s" % (self.property_name, _("highlight color"))) color_dialog.colorsel.set_current_color(self.highlight_color) color_dialog.ok_button.connect("clicked", self.highlight_color_dialog_ok, color_dialog) color_dialog.cancel_button.connect("clicked", self.highlight_color_dialog_cancel, color_dialog) color_dialog.connect("delete-event", self.highlight_color_dialog_close, color_dialog) color_dialog.run() def highlight_color_dialog_ok(self, widget, color_dialog): self.highlight_color = color_dialog.colorsel.get_current_color() color_dialog.destroy() self.update_example() def highlight_color_dialog_cancel(self, widget, color_dialog): color_dialog.destroy() def highlight_color_dialog_close(self, widget, extra, color_dialog): color_dialog.destroy() def update_example(self, widget=None): start = 0 end = len(self.example) attributes = pango.AttrList() attributes.insert( pango.AttrForeground(self.text_color.red, self.text_color.green, self.text_color.blue, start, end)) attributes.insert( pango.AttrBackground(self.highlight_color.red, self.highlight_color.green, self.highlight_color.blue, start, end)) # Bold verification if self.bold_tg_button.get_active(): attributes.insert(pango.AttrWeight(pango.WEIGHT_HEAVY, start, end)) else: attributes.insert(pango.AttrWeight(pango.WEIGHT_NORMAL, start, end)) # Italic verification if self.italic_tg_button.get_active(): attributes.insert(pango.AttrStyle(pango.STYLE_ITALIC, start, end)) else: attributes.insert(pango.AttrStyle(pango.STYLE_NORMAL, start, end)) # Underline verification if self.underline_tg_button.get_active(): attributes.insert( pango.AttrUnderline(pango.UNDERLINE_SINGLE, start, end)) else: attributes.insert( pango.AttrUnderline(pango.UNDERLINE_NONE, start, end)) self.example_label.set_attributes(attributes) def show_bold(self, widget): self.example_label.set_markup("<>") def get_example(self): return self.example_label.get_text() def set_example(self, example): self.example_label.set_text(example) def get_bold(self): if self.bold_tg_button.get_active(): return 1 return 0 def set_bold(self, bold): self.bold_tg_button.set_active(bold) def get_italic(self): if self.italic_tg_button.get_active(): return 1 return 0 def set_italic(self, italic): self.italic_tg_button.set_active(italic) def get_underline(self): if self.underline_tg_button.get_active(): return 1 return 0 def set_underline(self, underline): self.underline_tg_button.set_active(underline) def get_label(self): return self.property_name_label.get_text() def set_label(self, label): self.property_name_label.set_text(label) label = property(get_label, set_label) example = property(get_example, set_example) bold = property(get_bold, set_bold) italic = property(get_italic, set_italic) underline = property(get_underline, set_underline)
class UmitCredits(HIGWindow): def __init__(self): HIGWindow.__init__(self) self.set_title(_("%s credits") % UMIT_DISPLAY_NAME) self.set_size_request(-1, 250) self.set_position(gtk.WIN_POS_CENTER) self.__create_widgets() self.__packing() self.set_text() def __create_widgets(self): self.vbox = HIGVBox() self.hbox = HIGHBox() self.notebook = HIGNotebook() self.btn_close = HIGButton(stock=gtk.STOCK_CLOSE) self.written_by_scroll = HIGScrolledWindow() self.written_by_text = HIGTextView() self.design_scroll = HIGScrolledWindow() self.design_text = HIGTextView() self.soc2007_scroll = HIGScrolledWindow() self.soc2007_text = HIGTextView() self.contributors_scroll = HIGScrolledWindow() self.contributors_text = HIGTextView() self.translation_scroll = HIGScrolledWindow() self.translation_text = HIGTextView() self.nokia_scroll = HIGScrolledWindow() self.nokia_text = HIGTextView() def __packing(self): self.add(self.vbox) self.vbox.set_spacing(12) self.vbox._pack_expand_fill(self.notebook) self.vbox._pack_noexpand_nofill(self.hbox) self.hbox._pack_expand_fill(hig_box_space_holder()) self.hbox._pack_noexpand_nofill(self.btn_close) self.notebook.append_page( self.written_by_scroll, gtk.Label(_("Written by"))) self.notebook.append_page( self.design_scroll, gtk.Label(_("Design"))) self.notebook.append_page( self.soc2007_scroll, gtk.Label(_("SoC 2007"))) self.notebook.append_page( self.contributors_scroll, gtk.Label(_("Contributors"))) self.notebook.append_page( self.translation_scroll, gtk.Label(_("Translation"))) self.notebook.append_page( self.nokia_scroll, gtk.Label(_("Maemo"))) self.written_by_scroll.add(self.written_by_text) self.written_by_text.set_wrap_mode(gtk.WRAP_NONE) self.design_scroll.add(self.design_text) self.design_text.set_wrap_mode(gtk.WRAP_NONE) self.soc2007_scroll.add(self.soc2007_text) self.soc2007_text.set_wrap_mode(gtk.WRAP_NONE) self.contributors_scroll.add(self.contributors_text) self.contributors_text.set_wrap_mode(gtk.WRAP_NONE) self.translation_scroll.add(self.translation_text) self.translation_text.set_wrap_mode(gtk.WRAP_NONE) self.nokia_scroll.add(self.nokia_text) self.nokia_text.set_wrap_mode(gtk.WRAP_NONE) self.btn_close.connect('clicked', lambda x, y=None: self.destroy()) def set_text(self): b = self.written_by_text.get_buffer() b.set_text("""Adriano Monteiro Marques <*****@*****.**>""") b = self.design_text.get_buffer() b.set_text("""Operating System and Vulnerability Icons: Takeshi Alexandre Gondo <*****@*****.**> Logo, Application Icons and Splash screen: Virgílio Carlo de Menezes Vasconcelos <*****@*****.**> The Umit Project Web Site Design: Joao Paulo Pacheco <*****@*****.**>""") b = self.soc2007_text.get_buffer() b.set_text("""Independent Features: Adriano Monteiro Marques <*****@*****.**> Frederico Silva Ribeiro <*****@*****.**> Network Inventory: Guilherme Henrique Polo Gonçalves <*****@*****.**> Umit Radial Mapper: João Paulo de Souza Medeiros <*****@*****.**> Profile/Wizard interface editor: Luis Antonio Bastião Silva <*****@*****.**> NSE Facilitator: Maxim I. Gavrilov <*****@*****.**> Umit Web: Rodolfo da Silva Carvalho <*****@*****.**>""") b = self.contributors_text.get_buffer() b.set_text("""Sponsored by (SoC 2005, 2006 and 2007): Google <*****@*****.**> Mentor of Umit for Google SoC 2005 and 2006: Fyodor <*****@*****.**> Mentor of Umit for Google SoC 2007 Projects: Adriano Monteiro Marques <*****@*****.**> Initial development: Adriano Monteiro Marques <*****@*****.**> Cleber Rodrigues Rosa Junior <*****@*****.**> Nmap students from Google SoC 2007 that helped Umit: Eddie Bell <*****@*****.**> David Fifield <*****@*****.**> Kris Katterjohn <*****@*****.**> The Umit Project WebSite: AbraoBarbosa dos Santos Neto <*****@*****.**> Adriano Monteiro Marques <*****@*****.**> Heitor de Lima Matos <*****@*****.**> Joao Paulo Pacheco <*****@*****.**> João Paulo de Souza Medeiros <*****@*****.**> Luis Antonio Bastião Silva <*****@*****.**> Rodolfo da Silva Carvalho <*****@*****.**> Beta testers for 0.9.5RC1: Drew Miller <*****@*****.**> Igor Feghali <*****@*****.**> Joao Paulo Pacheco <*****@*****.**> Luis Antonio Bastião Silva <*****@*****.**> <*****@*****.**> <*****@*****.**> <*****@*****.**> Initial attempt on Maemo port: Adriano Monteiro Marques <*****@*****.**> Osvaldo Santana Neto <*****@*****.**>""") b = self.translation_text.get_buffer() b.set_text("""Brazilian Portuguese: Adriano Monteiro Marques <*****@*****.**>""") b = self.nokia_text.get_buffer() b.set_text("""Adriano Monteiro Marques <*****@*****.**>""")
class ProfileEditor(HIGWindow): def __init__(self, profile_name=None, deletable=True, overwrite=False): HIGWindow.__init__(self) self.connect("delete_event", self.exit) self.set_title(_('Profile Editor')) self.set_position(gtk.WIN_POS_CENTER) self.deletable = deletable self.profile_name = profile_name self.overwrite = overwrite self.__create_widgets() self.__pack_widgets() self.profile = CommandProfile() options_used = {} if profile_name: log.debug("Showing profile %s" % profile_name) prof = self.profile.get_profile(profile_name) options_used = prof['options'] # Interface settings self.profile_name_entry.set_text(profile_name) self.profile_description_text.get_buffer().set_text( prof['description']) self.constructor = CommandConstructor(options_used) ### self.profilehelp = ProfileHelp(options_used) ### self.options = OptionBuilder(Path.profile_editor, self.constructor, self.update_command, self.profilehelp) log.debug("Option groups: %s" % str(self.options.groups)) log.debug("Option section names: %s" % str(self.options.section_names)) #log.debug("Option tabs: %s" % str(self.options.tabs)) for tab in self.options.groups: self.__create_tab(tab, self.options.section_names[tab], self.options.tabs[tab]) self.update_command() def update_command(self): """Regenerate command with target '<target>' and set the value for the command entry""" self.command_entry.set_text(self.constructor.get_command('<target>')) ### whenever the command would be updated, thats when we update the help self.update_help() def update_help(self, text=None): helpText = self.help_field.get_buffer() if text: helpText.set_text(text) else: tempText = "" if self.profilehelp.get_currentstate() == "Default": helpText.set_text(" ") else: tempText += self.profilehelp.get_label() tempText += "\n\n" tempText += self.profilehelp.get_shortdesc() if self.profilehelp.get_example(): tempText += "\n\nExample input:\n" tempText += self.profilehelp.get_example() helpText.set_text(tempText) def update_help_name(self, widget, extra): self.update_help( text="Profile name\n\nThis is how the" + " profile will be identified in the drop-down combo box in the" + " scan tab.") def update_help_desc(self, widget, extra): self.update_help( text="Description\n\nThe description is a" + " full description of what the scan does, which may be long.") def help(self, widget): d = HIGAlertDialog( parent=self, message_format=_("Help not implemented"), secondary_text=_("Profile editor help is not implemented yet.")) d.run() d.destroy() def __create_widgets(self): ### # Vertical box to keep 3 boxes self.main_whole_box = HIGVBox() self.upper_box = HIGVBox() self.middle_box = HIGHBox() self.lower_box = HIGHBox() #self.main_vbox = HIGVBox() self.command_expander = HIGExpander('<b>' + _('Command') + '</b>') self.command_expander.set_expanded(True) self.command_entry = gtk.Entry() self.command_entry.set_editable(False) self.notebook = gtk.Notebook() # Profile info page self.profile_info_vbox = HIGVBox() self.profile_info_label = HIGSectionLabel(_('Profile Information')) self.profile_name_label = HIGEntryLabel(_('Profile name')) self.profile_name_entry = gtk.Entry() self.profile_name_entry.connect('enter-notify-event', self.update_help_name) self.profile_description_label = HIGEntryLabel(_('Description')) self.profile_description_scroll = HIGScrolledWindow() self.profile_description_scroll.set_border_width(0) self.profile_description_text = HIGTextView() self.profile_description_text.connect('motion-notify-event', self.update_help_desc) # Buttons self.buttons_hbox = HIGHBox() self.help_button = HIGButton(stock=gtk.STOCK_HELP) self.help_button.connect('clicked', self.help) self.cancel_button = HIGButton(stock=gtk.STOCK_CANCEL) self.cancel_button.connect('clicked', self.exit) self.delete_button = HIGButton(stock=gtk.STOCK_DELETE) self.delete_button.connect('clicked', self.delete_profile) self.ok_button = HIGButton(stock=gtk.STOCK_OK) self.ok_button.connect('clicked', self.save_profile) ### self.help_vbox = HIGVBox() self.help_label = HIGSectionLabel(_('Help')) self.help_scroll = HIGScrolledWindow() self.help_scroll.set_border_width(0) self.help_field = HIGTextView() self.help_field.set_cursor_visible(False) self.help_field.set_left_margin(5) self.help_field.set_editable(False) self.help_vbox.set_size_request(200, -1) ### def __pack_widgets(self): ### self.add(self.main_whole_box) # Packing command expander to upper box self.upper_box._pack_noexpand_nofill(self.command_expander) # Packing notebook (left) and help box (right) to middle box self.middle_box._pack_expand_fill(self.notebook) self.middle_box._pack_expand_fill(self.help_vbox) # Packing buttons to lower box self.lower_box.pack_end(self.buttons_hbox) # Packing the three vertical boxes to the main box self.main_whole_box._pack_noexpand_nofill(self.upper_box) self.main_whole_box._pack_noexpand_nofill(self.middle_box) self.main_whole_box._pack_noexpand_nofill(self.lower_box) ### # Packing command_entry on command_expander self.command_expander.hbox.pack_start(self.command_entry) # Packing profile information tab on notebook self.notebook.append_page(self.profile_info_vbox, gtk.Label(_('Profile'))) self.profile_info_vbox.set_border_width(5) table = HIGTable() self.profile_info_vbox._pack_noexpand_nofill(self.profile_info_label) self.profile_info_vbox._pack_expand_fill(HIGSpacer(table)) self.profile_description_scroll.add(self.profile_description_text) vbox_desc = HIGVBox() vbox_desc._pack_noexpand_nofill(self.profile_description_label) vbox_desc._pack_expand_fill(hig_box_space_holder()) vbox_ann = HIGVBox() vbox_ann._pack_expand_fill(hig_box_space_holder()) table.attach(self.profile_name_label, 0, 1, 0, 1, xoptions=0, yoptions=0) table.attach(self.profile_name_entry, 1, 2, 0, 1, yoptions=0) table.attach(vbox_desc, 0, 1, 1, 2, xoptions=0) table.attach(self.profile_description_scroll, 1, 2, 1, 2) # Packing buttons on button_hbox #self.buttons_hbox.pack_start(self.help_button) self.buttons_hbox._pack_expand_fill(hig_box_space_holder()) if self.deletable: self.buttons_hbox._pack_noexpand_nofill(self.delete_button) self.buttons_hbox._pack_noexpand_nofill(self.cancel_button) self.buttons_hbox._pack_noexpand_nofill(self.ok_button) self.buttons_hbox.set_border_width(5) self.buttons_hbox.set_spacing(6) ### self.help_vbox._pack_noexpand_nofill(self.help_label) self.help_vbox._pack_expand_fill(self.help_scroll) self.help_scroll.add(self.help_field) self.help_vbox.set_border_width(1) self.help_vbox.set_spacing(1) ### def __create_tab(self, tab_name, section_name, tab): log.debug(">>> Tab name: %s" % tab_name) log.debug(">>>Creating profile editor section: %s" % section_name) vbox = HIGVBox() table = HIGTable() table.set_row_spacings(2) section = HIGSectionLabel(section_name) vbox._pack_noexpand_nofill(section) vbox._pack_noexpand_nofill(HIGSpacer(table)) vbox.set_border_width(5) tab.fill_table(table, True) self.notebook.append_page(vbox, gtk.Label(tab_name)) def save_profile(self, widget): if self.overwrite: self.profile.remove_profile(self.profile_name) profile_name = self.profile_name_entry.get_text() if profile_name == '': alert = HIGAlertDialog(message_format=_('Unnamed profile'),\ secondary_text=_('You must provide a name \ for this profile.' )) alert.run() alert.destroy() self.profile_name_entry.grab_focus() return None command = self.constructor.get_command('%s') buf = self.profile_description_text.get_buffer() description = buf.get_text(buf.get_start_iter(),\ buf.get_end_iter()) self.profile.add_profile(profile_name,\ command=command,\ description=description,\ options=self.constructor.get_options()) self.scan_interface.toolbar.profile_entry.update() self.scan_interface.refresh_command(None) self.destroy() def clean_profile_info(self): self.profile_name_entry.set_text('') self.profile_description_text.get_buffer().set_text('') def set_scan_interface(self, interface): self.scan_interface = interface def exit(self, *args): self.destroy() def delete_profile(self, widget=None, extra=None): if self.deletable: dialog = HIGDialog(buttons=(gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)) alert = HIGEntryLabel('<b>' + _("Deleting Profile") + '</b>') text = HIGEntryLabel( _('Your profile is going to be deleted! Click\ Ok to continue, or Cancel to go back to Profile Editor.')) hbox = HIGHBox() hbox.set_border_width(5) hbox.set_spacing(12) vbox = HIGVBox() vbox.set_border_width(5) vbox.set_spacing(12) image = gtk.Image() image.set_from_stock(gtk.STOCK_DIALOG_WARNING, gtk.ICON_SIZE_DIALOG) vbox.pack_start(alert) vbox.pack_start(text) hbox.pack_start(image) hbox.pack_start(vbox) dialog.vbox.pack_start(hbox) dialog.vbox.show_all() response = dialog.run() dialog.destroy() if response == gtk.RESPONSE_CANCEL: return True self.profile.remove_profile(self.profile_name) self.update_profile_entry() self.destroy() def update_profile_entry(self, widget=None, extra=None): self.scan_interface.toolbar.profile_entry.update() list = self.scan_interface.toolbar.profile_entry.get_model() length = len(list) if length > 0: self.scan_interface.toolbar.profile_entry.set_active(0)
class DiffWindow(gtk.Window): def __init__(self, scans): gtk.Window.__init__(self) self.set_title(_("Compare Results")) self.ndiff_process = None # We allow the user to start a new diff before the old one has # finished. We have to keep references to old processes until they # finish to avoid problems when tearing down the Python interpreter at # program exit. self.old_processes = [] self.timer_id = None self.main_vbox = HIGVBox() self.diff_view = DiffView() self.diff_view.set_size_request(-1, 100) self.hbox_buttons = HIGHBox() self.progress = gtk.ProgressBar() self.btn_close = HIGButton(stock=gtk.STOCK_CLOSE) self.hbox_selection = HIGHBox() self.scan_chooser_a = ScanChooser(scans, _(u"A Scan")) self.scan_chooser_b = ScanChooser(scans, _(u"B Scan")) self._pack_widgets() self._connect_widgets() self.set_default_size(-1, 500) # Initial Size Request self.initial_size = self.get_size() def _pack_widgets(self): self.main_vbox.set_border_width(6) self.hbox_selection.pack_start(self.scan_chooser_a, True, True) self.hbox_selection.pack_start(self.scan_chooser_b, True, True) self.main_vbox.pack_start(self.hbox_selection, False) scroll = gtk.ScrolledWindow() scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scroll.add(self.diff_view) self.main_vbox.pack_start(scroll, True, True) self.progress.hide() self.progress.set_no_show_all(True) self.hbox_buttons.pack_start(self.progress, False) self.hbox_buttons.pack_end(self.btn_close, False) self.main_vbox._pack_noexpand_nofill(self.hbox_buttons) self.add(self.main_vbox) def _connect_widgets(self): self.connect("delete-event", self.close) self.btn_close.connect("clicked", self.close) self.scan_chooser_a.connect('changed', self.refresh_diff) self.scan_chooser_b.connect('changed', self.refresh_diff) def refresh_diff(self, widget): """This method is called whenever the diff output might have changed, such as when a different scan was selected in one of the choosers.""" log.debug("Refresh diff.") if (self.ndiff_process is not None and self.ndiff_process.poll() is None): # Put this in the list of old processes we keep track of. self.old_processes.append(self.ndiff_process) self.ndiff_process = None scan_a = self.scan_chooser_a.parsed_scan scan_b = self.scan_chooser_b.parsed_scan if scan_a is None or scan_b is None: self.diff_view.clear() else: try: self.ndiff_process = zenmapCore.Diff.ndiff(scan_a, scan_b) except OSError as e: alert = HIGAlertDialog( message_format=_("Error running ndiff"), secondary_text=_( "There was an error running the ndiff program.\n\n") + str(e).decode(sys.getdefaultencoding(), "replace")) alert.run() alert.destroy() else: self.progress.show() if self.timer_id is None: self.timer_id = gobject.timeout_add( NDIFF_CHECK_TIMEOUT, self.check_ndiff_process) def check_ndiff_process(self): """Check if the ndiff subprocess is done and show the diff if it is. Also remove any finished processes from the old process list.""" # Check if any old background processes have finished. for p in self.old_processes[:]: if p.poll() is not None: p.close() self.old_processes.remove(p) if self.ndiff_process is not None: # We're running the most recent scan. Check if it's done. status = self.ndiff_process.poll() if status is None: # Keep calling this function on a timer until the process # finishes. self.progress.pulse() return True if status == 0 or status == 1: # Successful completion. try: diff = self.ndiff_process.get_scan_diff() except zenmapCore.Diff.NdiffParseException as e: alert = HIGAlertDialog( message_format=_("Error parsing ndiff output"), secondary_text=str(e)) alert.run() alert.destroy() else: self.diff_view.show_diff(diff) else: # Unsuccessful completion. error_text = _( "The ndiff process terminated with status code %d." ) % status stderr = self.ndiff_process.stderr.read() if len(stderr) > 0: error_text += "\n\n" + stderr alert = HIGAlertDialog(message_format=_("Error running ndiff"), secondary_text=error_text) alert.run() alert.destroy() self.progress.hide() self.ndiff_process.close() self.ndiff_process = None if len(self.old_processes) > 0: # Keep calling this callback. return True else: # All done. self.timer_id = None return False def close(self, widget=None, extra=None): self.destroy()
class DateSubcriterion(Subcriterion): def __init__(self, operator="date", argument=""): Subcriterion.__init__(self) self.text2op = {"is": "date", "after": "after", "before": "before"} self.operator = operator self._create_widgets() self._pack_widgets() self._connect_widgets() # Count the fuzzy operators, so that we can append them to the argument later self.fuzzies = argument.count("~") argument = argument.replace("~", "") self.minus_notation = False if re.match("\d\d\d\d-\d\d-\d\d", argument) != None: year, month, day = argument.split("-") self.date = (int(year), int(month), int(day)) self.argument = argument elif re.match("[-|\+]\d+", argument) != None: # Convert the date from the "-n" notation into YYYY-MM-DD parsed_date = Date.fromordinal(Date.today().toordinal() + int(argument)) self.argument = argument self.date = (parsed_date.year, parsed_date.month, parsed_date.day) self.minus_notation = True else: self.date = localtime()[:3] self.argument = "%d-%02d-%02d" % (self.date[0], self.date[1], self.date[2]) # Append fuzzy operators, if any self.argument += "~" * self.fuzzies def _create_widgets(self): t = localtime() self.date_criterion_combo = gtk.combo_box_new_text() self.date_criterion_combo.append_text("is") self.date_criterion_combo.append_text("after") self.date_criterion_combo.append_text("before") if self.operator == "date": self.date_criterion_combo.set_active(0) elif self.operator == "after": self.date_criterion_combo.set_active(1) else: self.date_criterion_combo.set_active(2) self.date_button = HIGButton() def _pack_widgets(self): self.pack_start(self.date_criterion_combo, False) self.pack_start(self.date_button, True) def _connect_widgets(self): self.date_criterion_combo.connect("changed", self.date_criterion_changed) self.date_button.connect("clicked", self.show_calendar) def date_criterion_changed(self, widget=None, extra=None): self.operator = self.text2op[widget.get_active_text()] # Let the parent know that the operator has changed self.value_changed() def show_calendar(self, widget): calendar = DateCalendar() calendar.connect_calendar(self.update_button) calendar.show_all() def update_button(self, widget): date = list(widget.get_date()) date[1] += 1 # Add 1 to month, because calendar date is zero-based self.date = tuple(date) # Set the argument, using the search format year, month, day = self.date if self.minus_notation: # We need to calculate the date's offset from today, so that we can # represent the date in the "-n" notation selected_date = Date(year, month, day) today = Date.today() offset = selected_date.toordinal() - today.toordinal() if offset > 0: self.argument = "+" + str(offset) else: self.argument = str(offset) else: self.argument = "%d-%02d-%02d" % (year, month, day) self.argument += "~" * self.fuzzies # Let the parent know about the change self.value_changed() def set_date(self, date): # Localtime Format: (year, month, day) self.date_button.set_label("%02d %s %04d" % (date[2], months[date[1]][:3], date[0])) self._date = date def get_date(self): return self._date date = property(get_date, set_date) _date = localtime()[:3]
class Criterion(gtk.HBox): """This class holds one criterion row, represented as an HBox. It holds a ComboBox and a Subcriterion's subclass instance, depending on the selected entry in the ComboBox. For example, when the 'Target' option is selected, a SimpleSubcriterion widget is displayed, but when the 'Date' operator is selected, a DateSubcriterion widget is displayed.""" def __init__(self, search_window, operator="keyword", argument=""): """A reference to the search window is passed so that we can call add_criterion and remove_criterion.""" gtk.HBox.__init__(self) self.search_window = search_window self.default_operator = operator self.default_argument = argument # We need this as a map, so that we can pass the operator into # the SimpleSubcriterion instance self.combo_entries = { "Keyword": ["keyword"], "Profile Name": ["profile"], "Target": ["target"], "Options": ["option"], "Date": ["date", "after", "before"], "Operating System": ["os"], "Port": [ "open", "scanned", "closed", "filtered", "unfiltered", "open_filtered", "closed_filtered" ], "Service": ["service"], "Host In Route": ["inroute"], "Include Directory": ["dir"] } self._create_widgets() self._pack_widgets() self._connect_events() def _create_widgets(self): # A ComboBox containing the list of operators self.operator_combo = gtk.combo_box_new_text() # Sort all the keys from combo_entries and make an entry for each of them sorted_entries = self.combo_entries.keys() sorted_entries.sort() for name in sorted_entries: self.operator_combo.append_text(name) # Select the default operator for entry, operators in self.combo_entries.iteritems(): for operator in operators: if operator == self.default_operator: self.operator_combo.set_active(sorted_entries.index(entry)) break # Create a subcriterion self.subcriterion = self.new_subcriterion(self.default_operator, self.default_argument) # The "add" and "remove" buttons self.add_btn = HIGButton(" ", gtk.STOCK_ADD) self.remove_btn = HIGButton(" ", gtk.STOCK_REMOVE) def _pack_widgets(self): self.pack_start(self.operator_combo, False) self.pack_start(self.subcriterion, True, True) self.pack_start(self.add_btn, False) self.pack_start(self.remove_btn, False) def _connect_events(self): self.operator_combo.connect("changed", self.operator_changed) self.add_btn.connect("clicked", self.add_clicked) self.remove_btn.connect("clicked", self.remove_clicked) def get_operator(self): return self.subcriterion.operator def get_argument(self): return self.subcriterion.argument def add_clicked(self, widget=None, extra=None): self.search_window.add_criterion(self) def remove_clicked(self, widget=None, extra=None): self.search_window.remove_criterion(self) def value_changed(self, op, arg): """Subcriterion instances call this method when something changes inside of them.""" # We let the search window know about the change self.search_window.criterion_changed() def new_subcriterion(self, operator="keyword", argument=""): if operator in self.combo_entries["Date"]: return DateSubcriterion(operator, argument) elif operator in self.combo_entries["Port"]: return PortSubcriterion(operator, argument) elif operator == "dir": return DirSubcriterion(operator, argument) else: return SimpleSubcriterion(operator, argument) def operator_changed(self, widget=None, extra=None): """This function is called when the user selects a different entry in the Criterion's ComboBox.""" # Destroy the previous subcriterion self.subcriterion.destroy() # Create a new subcriterion depending on the selected operator selected = self.operator_combo.get_active_text() operator = self.combo_entries[selected][0] self.subcriterion = self.new_subcriterion(operator) # Pack it, and place it on the right side of the ComboBox self.pack_start(self.subcriterion, True, True) self.reorder_child(self.subcriterion, 1) # Notify the search window about the change self.search_window.criterion_changed() # Good to go self.subcriterion.show_all() operator = property(get_operator) argument = property(get_argument)
def _create_widgets(self): self.dir_entry = gtk.Entry() if self.argument: self.dir_entry.set_text(self.argument) self.chooser_btn = HIGButton("Choose...", gtk.STOCK_OPEN)
class SearchWindow(BaseSearchWindow, object): def __init__(self, load_method, append_method): BaseSearchWindow.__init__(self) self.set_default_size(600, 400) self.load_method = load_method self.append_method = append_method self._create_widgets() self._pack_widgets() self._connect_widgets() def _create_widgets(self): self.vbox = HIGVBox() self.bottom_hbox = gtk.HBox() self.bottom_label = gtk.Label() self.btn_box = gtk.HButtonBox() self.btn_open = HIGButton(stock=gtk.STOCK_OPEN) self.btn_append = HIGButton(_("Append"), gtk.STOCK_ADD) self.btn_close = HIGButton(stock=gtk.STOCK_CLOSE) self.search_gui = SearchGUI(self) def _pack_widgets(self): BaseSearchWindow._pack_widgets(self) self.btn_box.set_layout(gtk.BUTTONBOX_END) self.btn_box.set_spacing(4) self.btn_box.pack_start(self.btn_close) self.btn_box.pack_start(self.btn_append) self.btn_box.pack_start(self.btn_open) self.bottom_label.set_alignment(0.0, 0.5) self.bottom_label.set_use_markup(True) self.bottom_hbox.set_spacing(4) self.bottom_hbox.pack_start(self.bottom_label, True) self.bottom_hbox.pack_start(self.btn_box, False) self.vbox.set_spacing(4) self.vbox.pack_start(self.search_gui, True, True) self.vbox.pack_start(self.bottom_hbox, False) self.add(self.vbox) def _connect_widgets(self): # Double click on result, opens it self.search_gui.result_view.connect("row-activated", self.open_selected) self.btn_open.connect("clicked", self.open_selected) self.btn_append.connect("clicked", self.append_selected) self.btn_close.connect("clicked", self.close) self.connect("delete-event", self.close) def close(self, widget=None, event=None): self.search_gui.close() self.destroy() def set_label_text(self, text): self.bottom_label.set_label(text) def open_selected(self, widget=None, path=None, view_column=None, extra=None): # Open selected results self.load_method(self.results) # Close Search Window self.close() def append_selected(self, widget=None, path=None, view_column=None, extra=None): # Append selected results self.append_method(self.results) # Close Search Window self.close() def get_results(self): # Return list with parsed objects from result list store return self.search_gui.selected_results results = property(get_results)
class DiffWindow(gtk.Window): def __init__(self, scans): gtk.Window.__init__(self) self.set_title(_("Compare Results")) self.ndiff_process = None # We allow the user to start a new diff before the old one has # finished. We have to keep references to old processes until they # finish to avoid problems when tearing down the Python interpreter at # program exit. self.old_processes = [] self.timer_id = None self.main_vbox = HIGVBox() self.diff_view = DiffView() self.diff_view.set_size_request(-1, 100) self.hbox_buttons = HIGHBox() self.progress = gtk.ProgressBar() self.btn_close = HIGButton(stock=gtk.STOCK_CLOSE) self.hbox_selection = HIGHBox() self.scan_chooser_a = ScanChooser(scans, _(u"A Scan")) self.scan_chooser_b = ScanChooser(scans, _(u"B Scan")) self._pack_widgets() self._connect_widgets() self.set_default_size(-1, 500) # Initial Size Request self.initial_size = self.get_size() def _pack_widgets(self): self.main_vbox.set_border_width(6) self.hbox_selection.pack_start(self.scan_chooser_a, True, True) self.hbox_selection.pack_start(self.scan_chooser_b, True, True) self.main_vbox.pack_start(self.hbox_selection, False) scroll = gtk.ScrolledWindow() scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scroll.add(self.diff_view) self.main_vbox.pack_start(scroll, True, True) self.progress.hide() self.progress.set_no_show_all(True) self.hbox_buttons.pack_start(self.progress, False) self.hbox_buttons.pack_end(self.btn_close, False) self.main_vbox._pack_noexpand_nofill(self.hbox_buttons) self.add(self.main_vbox) def _connect_widgets(self): self.connect("delete-event", self.close) self.btn_close.connect("clicked", self.close) self.scan_chooser_a.connect('changed', self.refresh_diff) self.scan_chooser_b.connect('changed', self.refresh_diff) def refresh_diff(self, widget): """This method is called whenever the diff output might have changed, such as when a different scan was selected in one of the choosers.""" log.debug("Refresh diff.") if (self.ndiff_process is not None and self.ndiff_process.poll() is None): # Put this in the list of old processes we keep track of. self.old_processes.append(self.ndiff_process) self.ndiff_process = None scan_a = self.scan_chooser_a.parsed_scan scan_b = self.scan_chooser_b.parsed_scan if scan_a is None or scan_b is None: self.diff_view.clear() else: try: self.ndiff_process = zenmapCore.Diff.ndiff(scan_a, scan_b) except OSError, e: alert = HIGAlertDialog( message_format=_("Error running ndiff"), secondary_text=_( "There was an error running the ndiff program.\n\n") + str(e).decode(sys.getdefaultencoding(), "replace")) alert.run() alert.destroy() else:
class ProfileEditor(HIGWindow): def __init__(self, command=None, profile_name=None, deletable=True, overwrite=False): HIGWindow.__init__(self) self.connect("delete_event", self.exit) self.set_title(_('Profile Editor')) self.set_position(gtk.WIN_POS_CENTER) self.deletable = deletable self.profile_name = profile_name self.overwrite = overwrite # Used to block recursive updating of the command entry when the command # entry causes the OptionBuilder widgets to change. self.inhibit_command_update = False self.__create_widgets() self.__pack_widgets() self.profile = CommandProfile() self.ops = NmapOptions() if profile_name: log.debug("Showing profile %s" % profile_name) prof = self.profile.get_profile(profile_name) # Interface settings self.profile_name_entry.set_text(profile_name) self.profile_description_text.get_buffer().set_text(prof['description']) command_string = prof['command'] self.ops.parse_string(command_string) if command: self.ops.parse_string(command) self.option_builder = OptionBuilder(Path.profile_editor, self.ops, self.update_command, self.help_field.get_buffer()) log.debug("Option groups: %s" % str(self.option_builder.groups)) log.debug("Option section names: %s" % str(self.option_builder.section_names)) #log.debug("Option tabs: %s" % str(self.option_builder.tabs)) for tab in self.option_builder.groups: self.__create_tab(_(tab), _(self.option_builder.section_names[tab]), self.option_builder.tabs[tab]) self.update_command() def command_entry_changed_cb(self, widget): command_string = self.command_entry.get_text().decode("UTF-8") self.ops.parse_string(command_string) self.inhibit_command_update = True self.option_builder.update() self.inhibit_command_update = False def update_command(self): """Regenerate and display the command.""" if not self.inhibit_command_update: # Block recursive updating of the OptionBuilder widgets when they # cause a change in the command entry. self.command_entry.handler_block(self.command_entry_changed_cb_id) self.command_entry.set_text(self.ops.render_string()) self.command_entry.handler_unblock(self.command_entry_changed_cb_id) def update_help_name(self, widget, extra): self.help_field.get_buffer().set_text("Profile name\n\nThis is how the" +" profile will be identified in the drop-down combo box in the" +" scan tab.") def update_help_desc(self, widget, extra): self.help_field.get_buffer().set_text("Description\n\nThe description is a" + " full description of what the scan does, which may be long.") def __create_widgets(self): ### # Vertical box to keep 3 boxes self.main_whole_box = HIGVBox() self.upper_box = HIGHBox() self.middle_box = HIGHBox() self.lower_box = HIGHBox() #self.main_vbox = HIGVBox() self.command_entry = gtk.Entry() self.command_entry_changed_cb_id = \ self.command_entry.connect("changed", self.command_entry_changed_cb) self.scan_button = HIGButton(_("Scan")) self.scan_button.connect("clicked", self.run_scan) self.notebook = gtk.Notebook() # Profile info page self.profile_info_vbox = HIGVBox() self.profile_info_label = HIGSectionLabel(_('Profile Information')) self.profile_name_label = HIGEntryLabel(_('Profile name')) self.profile_name_entry = gtk.Entry() self.profile_name_entry.connect('enter-notify-event', self.update_help_name) self.profile_description_label = HIGEntryLabel(_('Description')) self.profile_description_scroll = HIGScrolledWindow() self.profile_description_scroll.set_border_width(0) self.profile_description_text = HIGTextView() self.profile_description_text.connect('motion-notify-event', self.update_help_desc) # Buttons self.buttons_hbox = HIGHBox() self.cancel_button = HIGButton(stock=gtk.STOCK_CANCEL) self.cancel_button.connect('clicked', self.exit) self.delete_button = HIGButton(stock=gtk.STOCK_DELETE) self.delete_button.connect('clicked', self.delete_profile) self.save_button = HIGButton(_("Save Changes"), stock=gtk.STOCK_SAVE) self.save_button.connect('clicked', self.save_profile) ### self.help_vbox = HIGVBox() self.help_label = HIGSectionLabel(_('Help')) self.help_scroll = HIGScrolledWindow() self.help_scroll.set_border_width(0) self.help_field = HIGTextView() self.help_field.set_cursor_visible(False) self.help_field.set_left_margin(5) self.help_field.set_editable(False) self.help_vbox.set_size_request(200,-1) ### def __pack_widgets(self): ### self.add(self.main_whole_box) # Packing command entry to upper box self.upper_box._pack_expand_fill(self.command_entry) self.upper_box._pack_noexpand_nofill(self.scan_button) # Packing notebook (left) and help box (right) to middle box self.middle_box._pack_expand_fill(self.notebook) self.middle_box._pack_expand_fill(self.help_vbox) # Packing buttons to lower box self.lower_box.pack_end(self.buttons_hbox) # Packing the three vertical boxes to the main box self.main_whole_box._pack_noexpand_nofill(self.upper_box) self.main_whole_box._pack_expand_fill(self.middle_box) self.main_whole_box._pack_noexpand_nofill(self.lower_box) ### # Packing profile information tab on notebook self.notebook.append_page(self.profile_info_vbox, gtk.Label(_('Profile'))) self.profile_info_vbox.set_border_width(5) table = HIGTable() self.profile_info_vbox._pack_noexpand_nofill(self.profile_info_label) self.profile_info_vbox._pack_expand_fill(HIGSpacer(table)) self.profile_description_scroll.add(self.profile_description_text) vbox_desc = HIGVBox() vbox_desc._pack_noexpand_nofill(self.profile_description_label) vbox_desc._pack_expand_fill(hig_box_space_holder()) vbox_ann = HIGVBox() vbox_ann._pack_expand_fill(hig_box_space_holder()) table.attach(self.profile_name_label,0,1,0,1,xoptions=0,yoptions=0) table.attach(self.profile_name_entry,1,2,0,1,yoptions=0) table.attach(vbox_desc,0,1,1,2,xoptions=0) table.attach(self.profile_description_scroll,1,2,1,2) # Packing buttons on button_hbox self.buttons_hbox._pack_expand_fill(hig_box_space_holder()) if self.deletable: self.buttons_hbox._pack_noexpand_nofill(self.delete_button) self.buttons_hbox._pack_noexpand_nofill(self.cancel_button) self.buttons_hbox._pack_noexpand_nofill(self.save_button) self.buttons_hbox.set_border_width(5) self.buttons_hbox.set_spacing(6) ### self.help_vbox._pack_noexpand_nofill(self.help_label) self.help_vbox._pack_expand_fill(self.help_scroll) self.help_scroll.add(self.help_field) self.help_vbox.set_border_width(1) self.help_vbox.set_spacing(1) ### def __create_tab(self, tab_name, section_name, tab): log.debug(">>> Tab name: %s" % tab_name) log.debug(">>>Creating profile editor section: %s" % section_name) vbox = HIGVBox() if tab.notscripttab: # if notscripttab is set table = HIGTable() table.set_row_spacings(2) section = HIGSectionLabel(section_name) vbox._pack_noexpand_nofill(section) vbox._pack_noexpand_nofill(HIGSpacer(table)) vbox.set_border_width(5) tab.fill_table(table, True) else: hbox = tab.get_hmain_box() vbox.pack_start(hbox,True,True,0) self.notebook.append_page(vbox, gtk.Label(tab_name)) def save_profile(self, widget): if self.overwrite: self.profile.remove_profile(self.profile_name) profile_name = self.profile_name_entry.get_text() if profile_name == '': alert = HIGAlertDialog(message_format=_('Unnamed profile'),\ secondary_text=_('You must provide a name \ for this profile.')) alert.run() alert.destroy() self.profile_name_entry.grab_focus() return None command = self.ops.render_string() buf = self.profile_description_text.get_buffer() description = buf.get_text(buf.get_start_iter(),\ buf.get_end_iter()) try: self.profile.add_profile(profile_name,\ command=command,\ description=description) except ValueError: alert = HIGAlertDialog(message_format=_('Disallowed profile name'),\ secondary_text=_('Sorry, the name "%s" \ is not allowed due to technical limitations. (The underlying ConfigParser \ used to store profiles does not allow it.) Choose a different \ name.' % profile_name)) alert.run() alert.destroy() return self.scan_interface.toolbar.profile_entry.update() self.destroy() def clean_profile_info(self): self.profile_name_entry.set_text('') self.profile_description_text.get_buffer().set_text('') def set_scan_interface(self, interface): self.scan_interface = interface def exit(self, *args): self.destroy() def delete_profile(self, widget=None, extra=None): if self.deletable: dialog = HIGDialog(buttons=(gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)) alert = HIGEntryLabel('<b>'+_("Deleting Profile")+'</b>') text = HIGEntryLabel(_('Your profile is going to be deleted! Click\ Ok to continue, or Cancel to go back to Profile Editor.')) hbox = HIGHBox() hbox.set_border_width(5) hbox.set_spacing(12) vbox = HIGVBox() vbox.set_border_width(5) vbox.set_spacing(12) image = gtk.Image() image.set_from_stock(gtk.STOCK_DIALOG_WARNING, gtk.ICON_SIZE_DIALOG) vbox.pack_start(alert) vbox.pack_start(text) hbox.pack_start(image) hbox.pack_start(vbox) dialog.vbox.pack_start(hbox) dialog.vbox.show_all() response = dialog.run() dialog.destroy() if response == gtk.RESPONSE_CANCEL: return True self.profile.remove_profile(self.profile_name) self.update_profile_entry() self.destroy() def run_scan(self, widget=None): command_string = self.command_entry.get_text().decode("UTF-8") self.scan_interface.command_toolbar.command = command_string self.scan_interface.start_scan_cb() self.exit() def update_profile_entry(self, widget=None, extra=None): self.scan_interface.toolbar.profile_entry.update() list = self.scan_interface.toolbar.profile_entry.get_model() length = len(list) if length >0 : self.scan_interface.toolbar.profile_entry.set_active(0)
class HighlightProperty(object): def __init__(self, property_name, property): self.__create_widgets() self.property_name = property_name self.property_label = property[0].capitalize() self.example = property[1] self.bold = property[2] self.italic = property[3] self.underline = property[4] self.text_color = property[5] self.highlight_color = property[6] self.__connect_buttons() def __create_widgets(self): self.property_name_label = HIGEntryLabel("") self.example_label = HIGEntryLabel("") self.bold_tg_button = HIGToggleButton("", gtk.STOCK_BOLD) self.italic_tg_button = HIGToggleButton("", gtk.STOCK_ITALIC) self.underline_tg_button = HIGToggleButton("", gtk.STOCK_UNDERLINE) self.text_color_button = HIGButton( _("Text"), stock=gtk.STOCK_SELECT_COLOR) self.highlight_color_button = HIGButton( _("Highlight"), stock=gtk.STOCK_SELECT_COLOR) def __connect_buttons(self): self.bold_tg_button.connect("toggled", self.update_example) self.italic_tg_button.connect("toggled", self.update_example) self.underline_tg_button.connect("toggled", self.update_example) self.text_color_button.connect("clicked", self.text_color_dialog) self.highlight_color_button.connect( "clicked", self.highlight_color_dialog) #################################### # Text color dialog def text_color_dialog(self, widget): color_dialog = gtk.ColorSelectionDialog( "%s %s" % (self.label, _("text color"))) color_dialog.colorsel.set_current_color(self.text_color) color_dialog.ok_button.connect( "clicked", self.text_color_dialog_ok, color_dialog) color_dialog.cancel_button.connect( "clicked", self.text_color_dialog_cancel, color_dialog) color_dialog.connect( "delete-event", self.text_color_dialog_close, color_dialog) color_dialog.run() def text_color_dialog_ok(self, widget, color_dialog): self.text_color = color_dialog.colorsel.get_current_color() color_dialog.destroy() self.update_example() def text_color_dialog_cancel(self, widget, color_dialog): color_dialog.destroy() def text_color_dialog_close(self, widget, extra, color_dialog): color_dialog.destroy() ######################################### # Highlight color dialog def highlight_color_dialog(self, widget): color_dialog = gtk.ColorSelectionDialog( "%s %s" % (self.property_name, _("highlight color"))) color_dialog.colorsel.set_current_color(self.highlight_color) color_dialog.ok_button.connect( "clicked", self.highlight_color_dialog_ok, color_dialog) color_dialog.cancel_button.connect( "clicked", self.highlight_color_dialog_cancel, color_dialog) color_dialog.connect( "delete-event", self.highlight_color_dialog_close, color_dialog) color_dialog.run() def highlight_color_dialog_ok(self, widget, color_dialog): self.highlight_color = color_dialog.colorsel.get_current_color() color_dialog.destroy() self.update_example() def highlight_color_dialog_cancel(self, widget, color_dialog): color_dialog.destroy() def highlight_color_dialog_close(self, widget, extra, color_dialog): color_dialog.destroy() def update_example(self, widget=None): start = 0 end = len(self.example) attributes = pango.AttrList() attributes.insert( pango.AttrForeground(self.text_color.red, self.text_color.green, self.text_color.blue, start, end)) attributes.insert(pango.AttrBackground(self.highlight_color.red, self.highlight_color.green, self.highlight_color.blue, start, end)) # Bold verification if self.bold_tg_button.get_active(): attributes.insert(pango.AttrWeight(pango.WEIGHT_HEAVY, start, end)) else: attributes.insert( pango.AttrWeight(pango.WEIGHT_NORMAL, start, end)) # Italic verification if self.italic_tg_button.get_active(): attributes.insert(pango.AttrStyle(pango.STYLE_ITALIC, start, end)) else: attributes.insert(pango.AttrStyle(pango.STYLE_NORMAL, start, end)) # Underline verification if self.underline_tg_button.get_active(): attributes.insert( pango.AttrUnderline(pango.UNDERLINE_SINGLE, start, end)) else: attributes.insert( pango.AttrUnderline(pango.UNDERLINE_NONE, start, end)) self.example_label.set_attributes(attributes) def show_bold(self, widget): self.example_label.set_markup("<>") def get_example(self): return self.example_label.get_text() def set_example(self, example): self.example_label.set_text(example) def get_bold(self): if self.bold_tg_button.get_active(): return 1 return 0 def set_bold(self, bold): self.bold_tg_button.set_active(bold) def get_italic(self): if self.italic_tg_button.get_active(): return 1 return 0 def set_italic(self, italic): self.italic_tg_button.set_active(italic) def get_underline(self): if self.underline_tg_button.get_active(): return 1 return 0 def set_underline(self, underline): self.underline_tg_button.set_active(underline) def get_label(self): return self.property_name_label.get_text() def set_label(self, label): self.property_name_label.set_text(label) label = property(get_label, set_label) example = property(get_example, set_example) bold = property(get_bold, set_bold) italic = property(get_italic, set_italic) underline = property(get_underline, set_underline)
class DiffWindow(gtk.Window): def __init__(self, scans): gtk.Window.__init__(self) self.set_title(_("Compare Results")) self.ndiff_process = None # We allow the user to start a new diff before the old one has # finished. We have to keep references to old processes until they # finish to avoid problems when tearing down the Python interpreter at # program exit. self.old_processes = [] self.timer_id = None self.main_vbox = HIGVBox() self.diff_view = DiffView() self.diff_view.set_size_request(-1, 100) self.hbox_buttons = HIGHBox() self.progress = gtk.ProgressBar() self.btn_close = HIGButton(stock=gtk.STOCK_CLOSE) self.hbox_selection = HIGHBox() self.scan_chooser_a = ScanChooser(scans, _(u"A Scan")) self.scan_chooser_b = ScanChooser(scans, _(u"B Scan")) self._pack_widgets() self._connect_widgets() self.set_default_size(-1, 500) # Initial Size Request self.initial_size = self.get_size() def _pack_widgets(self): self.main_vbox.set_border_width(6) self.hbox_selection.pack_start(self.scan_chooser_a, True, True) self.hbox_selection.pack_start(self.scan_chooser_b, True, True) self.main_vbox.pack_start(self.hbox_selection, False) scroll = gtk.ScrolledWindow() scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scroll.add(self.diff_view) self.main_vbox.pack_start(scroll, True, True) self.progress.hide() self.progress.set_no_show_all(True) self.hbox_buttons.pack_start(self.progress, False) self.hbox_buttons.pack_end(self.btn_close, False) self.main_vbox._pack_noexpand_nofill(self.hbox_buttons) self.add(self.main_vbox) def _connect_widgets(self): self.connect("delete-event", self.close) self.btn_close.connect("clicked", self.close) self.scan_chooser_a.connect('changed', self.refresh_diff) self.scan_chooser_b.connect('changed', self.refresh_diff) def refresh_diff(self, widget): """This method is called whenever the diff output might have changed, such as when a different scan was selected in one of the choosers.""" log.debug("Refresh diff.") if (self.ndiff_process is not None and self.ndiff_process.poll() is None): # Put this in the list of old processes we keep track of. self.old_processes.append(self.ndiff_process) self.ndiff_process = None scan_a = self.scan_chooser_a.parsed_scan scan_b = self.scan_chooser_b.parsed_scan if scan_a is None or scan_b is None: self.diff_view.clear() else: try: self.ndiff_process = zenmapCore.Diff.ndiff(scan_a, scan_b) except OSError as e: alert = HIGAlertDialog( message_format=_("Error running ndiff"), secondary_text=_( "There was an error running the ndiff program.\n\n" ) + str(e).decode(sys.getdefaultencoding(), "replace")) alert.run() alert.destroy() else: self.progress.show() if self.timer_id is None: self.timer_id = gobject.timeout_add( NDIFF_CHECK_TIMEOUT, self.check_ndiff_process) def check_ndiff_process(self): """Check if the ndiff subprocess is done and show the diff if it is. Also remove any finished processes from the old process list.""" # Check if any old background processes have finished. for p in self.old_processes[:]: if p.poll() is not None: p.close() self.old_processes.remove(p) if self.ndiff_process is not None: # We're running the most recent scan. Check if it's done. status = self.ndiff_process.poll() if status is None: # Keep calling this function on a timer until the process # finishes. self.progress.pulse() return True if status == 0 or status == 1: # Successful completion. try: diff = self.ndiff_process.get_scan_diff() except zenmapCore.Diff.NdiffParseException as e: alert = HIGAlertDialog( message_format=_("Error parsing ndiff output"), secondary_text=str(e)) alert.run() alert.destroy() else: self.diff_view.show_diff(diff) else: # Unsuccessful completion. error_text = _( "The ndiff process terminated with status code %d." ) % status stderr = self.ndiff_process.stderr.read() if len(stderr) > 0: error_text += "\n\n" + stderr alert = HIGAlertDialog( message_format=_("Error running ndiff"), secondary_text=error_text) alert.run() alert.destroy() self.progress.hide() self.ndiff_process.close() self.ndiff_process = None if len(self.old_processes) > 0: # Keep calling this callback. return True else: # All done. self.timer_id = None return False def close(self, widget=None, extra=None): self.destroy()
class ScriptInterface: # Timeout, in milliseconds, after the user stops typing and we update the # interface from --script. SCRIPT_LIST_DELAY = 500 # Timeout, in milliseconds, between polls of the Nmap subprocess. NMAP_DELAY = 200 def __init__(self, root_tabs, ops, update_command, help_buf): self.hmainbox = HIGHBox(False, 0) self.notscripttab = False # show profile editor it is a script tab self.nmap_process = None self.script_list_timeout_id = None self.nmap_timeout_id = None self.chk_nmap_timeout_id = None self.script_file_chooser = None self.ops = ops self.update_command = update_command self.help_buf = help_buf self.arg_values = {} self.current_arguments = [] self.set_help_texts() self.prev_script_spec = None self.focusedentry = None self.liststore = gtk.ListStore(str, "gboolean", object) self.file_liststore = gtk.ListStore(str, "gboolean") # Arg name, arg value, (name, desc) tuple. self.arg_liststore = gtk.ListStore(str, str, object) # This is what is shown initially. After the initial Nmap run to get # the list of script is finished, this will be replaced with a TreeView # showing the scripts or an error message. self.script_list_container = gtk.VBox() self.script_list_container.pack_start(self.make_please_wait_widget()) self.hmainbox.pack_start(self.script_list_container, False, False, 0) self.nmap_error_widget = gtk.Label( _("There was an error getting the list of scripts from Nmap. " "Try upgrading Nmap.")) self.nmap_error_widget.set_line_wrap(True) self.nmap_error_widget.show_all() self.script_list_widget = self.make_script_list_widget() self.script_list_widget.show_all() vbox = HIGVBox(False, 5) vbox.pack_start(self.make_description_widget(), True, True, 0) vbox.pack_start(self.make_arguments_widget(), True, True, 0) self.hmainbox.pack_end(vbox, True, True, 0) self.update_argument_values(self.ops["--script-args"]) # Start the initial backgrounded Nmap run to get the list of all # available scripts. self.get_script_list("all", self.initial_script_list_cb) def get_script_list(self, rules, callback): """Start an Nmap subprocess in the background with "--script-help=<rules> -oX -", and set it up to call the given callback when finished.""" ops = NmapOptions() ops.executable = paths_config.nmap_command_path ops["--script-help"] = rules ops["-oX"] = "-" command_string = ops.render_string() # Separate stderr to avoid breaking XML parsing with "Warning: File # ./nse_main.lua exists, but Nmap is using...". stderr = tempfile.TemporaryFile(mode="rb", prefix=APP_NAME + "-script-help-stderr-") log.debug("Script interface: running %s" % repr(command_string)) nmap_process = NmapCommand(command_string) try: nmap_process.run_scan(stderr=stderr) except Exception as e: callback(False, None) stderr.close() return stderr.close() self.script_list_widget.set_sensitive(False) gobject.timeout_add(self.NMAP_DELAY, self.script_list_timer_callback, nmap_process, callback) def script_list_timer_callback(self, process, callback): try: status = process.scan_state() except Exception: status = None log.debug("Script interface: script_list_timer_callback %s" % repr(status)) if status is True: # Still running, schedule this timer to check again. return True self.script_list_widget.set_sensitive(True) if status is False: # Finished with success. callback(True, process) else: # Finished with error. callback(False, process) def initial_script_list_cb(self, status, process): log.debug("Script interface: initial_script_list_cb %s" % repr(status)) for child in self.script_list_container.get_children(): self.script_list_container.remove(child) if status and self.handle_initial_script_list_output(process): self.script_list_container.pack_start(self.script_list_widget) else: self.script_list_container.pack_start(self.nmap_error_widget) def handle_initial_script_list_output(self, process): process.stdout_file.seek(0) try: handler = ScriptHelpXMLContentHandler.parse_nmap_script_help( process.stdout_file) except (ValueError, xml.sax.SAXParseException) as e: log.debug("--script-help parse exception: %s" % str(e)) return False # Check if any scripts were output; if not, Nmap is probably too old. if len(handler.script_filenames) == 0: return False if not handler.scripts_dir: log.debug("--script-help error: no scripts directory") return False if not handler.nselib_dir: log.debug("--script-help error: no nselib directory") return False log.debug("Script interface: scripts dir %s" % repr(handler.scripts_dir)) log.debug("Script interface: nselib dir %s" % repr(handler.nselib_dir)) # Make a dict of script metadata entries. entries = {} for entry in get_script_entries(handler.scripts_dir, handler.nselib_dir): entries[entry.filename] = entry self.liststore.clear() for filename in handler.script_filenames: basename = os.path.basename(filename) entry = entries.get(basename) if entry: script_id = self.strip_file_name(basename) self.liststore.append([script_id, False, entry]) else: # ScriptMetadata found nothing for this script? self.file_liststore.append([filename, False]) # Now figure out which scripts are selected. self.update_script_list_from_spec(self.ops["--script"]) return True def update_script_list_from_spec(self, spec): """Callback method for user edit delay.""" log.debug("Script interface: update_script_list_from_spec %s" % repr(spec)) if spec: self.get_script_list(spec, self.update_script_list_cb) else: self.refresh_list_scripts([]) def update_script_list_cb(self, status, process): log.debug("Script interface: update_script_list_cb %s" % repr(status)) if status: self.handle_update_script_list_output(process) else: self.refresh_list_scripts([]) def handle_update_script_list_output(self, process): process.stdout_file.seek(0) try: handler = ScriptHelpXMLContentHandler.parse_nmap_script_help( process.stdout_file) except (ValueError, xml.sax.SAXParseException) as e: log.debug("--script-help parse exception: %s" % str(e)) return False self.refresh_list_scripts(handler.script_filenames) def get_hmain_box(self): """Returns main Hbox to ProfileEditor.""" return self.hmainbox def update(self): """Updates the interface when the command entry is changed.""" # updates list of scripts rules = self.ops["--script"] if (self.prev_script_spec != rules): self.renew_script_list_timer(rules) self.prev_script_spec = rules # updates arguments.. raw_argument = self.ops["--script-args"] if raw_argument is not None: self.parse_script_args(raw_argument) self.arg_liststore.clear() for arg in self.current_arguments: arg_name, arg_desc = arg value = self.arg_values.get(arg_name) if not value: self.arg_liststore.append([arg_name, None, arg]) else: self.arg_liststore.append([arg_name, value, arg]) def renew_script_list_timer(self, spec): """Restart the timer to update the script list when the user edits the command. Because updating the script list is an expensive operation involving the creation of a subprocess, we don't do it for every typed character.""" if self.script_list_timeout_id: gobject.source_remove(self.script_list_timeout_id) self.script_list_timeout_id = gobject.timeout_add( self.SCRIPT_LIST_DELAY, self.update_script_list_from_spec, spec) def parse_script_args(self, raw_argument): """When the command line is edited, this function is called to update the script arguments display according to the value of --script-args.""" arg_dict = parse_script_args_dict(raw_argument) if arg_dict is None: # if there is parsing error args_dict holds none self.arg_values.clear() else: self.arg_values.update(arg_dict) def update_argument_values(self, raw_argument): """When scripting tab starts up, argument values are updated.""" if raw_argument is not None: self.parse_script_args(raw_argument) def set_help_texts(self): """Sets the help texts to be displayed.""" self.list_scripts_help = _("""List of scripts A list of all installed scripts. Activate or deactivate a script \ by clicking the box next to the script name.""") self.description_help = _("""Description This box shows the categories a script belongs to. In addition, it gives a \ detailed description of the script which is present in script. A URL points \ to online NSEDoc documentation.""") self.argument_help = _("""Arguments A list of arguments that affect the selected script. Enter a value by \ clicking in the value field beside the argument name.""") def make_please_wait_widget(self): vbox = gtk.VBox() label = gtk.Label(_("Please wait.")) label.set_line_wrap(True) vbox.pack_start(label) return vbox def make_script_list_widget(self): """Creates and packs widgets associated with left hand side of Interface.""" vbox = gtk.VBox() scrolled_window = HIGScrolledWindow() scrolled_window.set_policy(gtk.POLICY_ALWAYS, gtk.POLICY_ALWAYS) # Expand only vertically. scrolled_window.set_size_request(175, -1) listview = gtk.TreeView(self.liststore) listview.set_headers_visible(False) listview.connect("enter-notify-event", self.update_help_ls_cb) selection = listview.get_selection() selection.connect("changed", self.selection_changed_cb) cell = gtk.CellRendererText() togglecell = gtk.CellRendererToggle() togglecell.set_property("activatable", True) togglecell.connect("toggled", self.toggled_cb, self.liststore) col = gtk.TreeViewColumn(_('Names')) col.set_sizing(gtk.TREE_VIEW_COLUMN_GROW_ONLY) col.set_resizable(True) togglecol = gtk.TreeViewColumn(None, togglecell) togglecol.add_attribute(togglecell, "active", 1) listview.append_column(togglecol) listview.append_column(col) col.pack_start(cell, True) col.add_attribute(cell, "text", 0) scrolled_window.add(listview) scrolled_window.show() vbox.pack_start(scrolled_window, True, True, 0) self.file_scrolled_window = HIGScrolledWindow() self.file_scrolled_window.set_policy(gtk.POLICY_ALWAYS, gtk.POLICY_ALWAYS) self.file_scrolled_window.set_size_request(175, -1) self.file_scrolled_window.hide() self.file_scrolled_window.set_no_show_all(True) self.file_listview = gtk.TreeView(self.file_liststore) self.file_listview.set_headers_visible(False) col = gtk.TreeViewColumn(None) self.file_listview.append_column(col) cell = gtk.CellRendererToggle() col.pack_start(cell, True) cell.set_property("activatable", True) col.add_attribute(cell, "active", 1) cell.connect("toggled", self.toggled_cb, self.file_liststore) col = gtk.TreeViewColumn(None) self.file_listview.append_column(col) cell = gtk.CellRendererText() col.pack_start(cell) col.add_attribute(cell, "text", 0) self.file_listview.show_all() self.file_scrolled_window.add(self.file_listview) vbox.pack_start(self.file_scrolled_window, False) hbox = HIGHBox(False, 2) self.remove_file_button = HIGButton(stock=gtk.STOCK_REMOVE) self.remove_file_button.connect("clicked", self.remove_file_button_clicked_cb) self.remove_file_button.set_sensitive(False) hbox.pack_end(self.remove_file_button) add_file_button = HIGButton(stock=gtk.STOCK_ADD) add_file_button.connect("clicked", self.add_file_button_clicked_cb) hbox.pack_end(add_file_button) vbox.pack_start(hbox, False, False, 0) return vbox def refresh_list_scripts(self, selected_scripts): """The list of selected scripts is refreshed in the list store.""" for row in self.liststore: row[1] = False for row in self.file_liststore: row[1] = False for filename in selected_scripts: for row in self.liststore: if row[0] == self.strip_file_name(os.path.basename(filename)): row[1] = True break else: for row in self.file_liststore: if row[0] == filename: row[1] = True break else: self.file_liststore.append([filename, True]) def strip_file_name(self, filename): """Removes a ".nse" extension from filename if present.""" if (filename.endswith(".nse")): return filename[:-4] else: return filename def set_script_from_selection(self): scriptsname = [] for entry in self.liststore: if entry[1]: scriptsname.append(self.strip_file_name(entry[0])) for entry in self.file_liststore: if entry[1]: scriptsname.append(entry[0]) if len(scriptsname) == 0: self.ops["--script"] = None else: self.ops["--script"] = ",".join(scriptsname) self.update_command() def toggled_cb(self, cell, path, model): """Callback method, called when the check box in list of scripts is toggled.""" model[path][1] = not model[path][1] self.set_script_from_selection() def make_description_widget(self): """Creates and packs widgets related to displaying the description box.""" sw = HIGScrolledWindow() sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS) sw.set_shadow_type(gtk.SHADOW_OUT) sw.set_border_width(5) text_view = gtk.TextView() text_view.connect("enter-notify-event", self.update_help_desc_cb) self.text_buffer = text_view.get_buffer() self.text_buffer.create_tag("Usage", font="Monospace") self.text_buffer.create_tag("Output", font="Monospace") text_view.set_wrap_mode(gtk.WRAP_WORD) text_view.set_editable(False) text_view.set_justification(gtk.JUSTIFY_LEFT) sw.add(text_view) return sw def make_arguments_widget(self): """Creates and packs widgets related to arguments box.""" vbox = gtk.VBox() vbox.pack_start(gtk.Label(_("Arguments")), False, False, 0) arg_window = HIGScrolledWindow() arg_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS) arg_window.set_shadow_type(gtk.SHADOW_OUT) arg_listview = gtk.TreeView(self.arg_liststore) arg_listview.connect("motion-notify-event", self.update_help_arg_cb) argument = gtk.CellRendererText() self.value = gtk.CellRendererText() self.value.connect("edited", self.value_edited_cb, self.arg_liststore) arg_col = gtk.TreeViewColumn("Arguments\t") val_col = gtk.TreeViewColumn("values") arg_listview.append_column(arg_col) arg_listview.append_column(val_col) arg_col.pack_start(argument, True) arg_col.add_attribute(argument, "text", 0) val_col.pack_start(self.value, True) val_col.add_attribute(self.value, "text", 1) arg_window.add(arg_listview) vbox.pack_start(arg_window, True, True, 0) return vbox def value_edited_cb(self, cell, path, new_text, model): """Called when the argument cell is edited.""" self.arg_list = [] model[path][1] = new_text argument_name = model[path][0] self.arg_values[argument_name] = new_text self.update_arg_values() def update_arg_values(self): """When the widget is updated with argument value, correspondingly update the command line.""" for key in self.arg_values: if len(self.arg_values[key]) == 0: del self.arg_values[key] else: self.arg_list.append(key + "=" + self.arg_values[key]) if len(self.arg_list) == 0: self.ops["--script-args"] = None self.arg_values.clear() else: self.ops["--script-args"] = ",".join(self.arg_list) self.update_command() def selection_changed_cb(self, selection): """Called back when the list of scripts is selected.""" model, selection = selection.get_selected_rows() for path in selection: entry = model.get_value(model.get_iter(path), 2) self.set_description(entry) self.populate_arg_list(entry) # Remember the currently pointing script entry self.focusedentry = entry def update_help_ls_cb(self, widget, extra): # list of scripts """Callback method to display the help for the list of scripts.""" self.help_buf.set_text(self.list_scripts_help) def update_help_desc_cb(self, widget, extra): """Callback method for displaying description.""" self.help_buf.set_text(self.description_help) def update_help_arg_cb(self, treeview, event): """Callback method for displaying argument help.""" wx, wy = treeview.get_pointer() try: x, y = treeview.convert_widget_to_bin_window_coords(wx, wy) except AttributeError: # convert_widget_to_bin_window_coords was introduced in PyGTK 2.12. return path = treeview.get_path_at_pos(x, y) if not path or not self.focusedentry: self.help_buf.set_text("") return path = path[0] model, selected = treeview.get_selection().get_selected() arg_name, arg_desc = model.get_value(model.get_iter(path), 2) if arg_desc is not None: self.help_buf.set_text("") self.help_buf.insert(self.help_buf.get_end_iter(), text="%s\n" % arg_name) text_buffer_insert_nsedoc(self.help_buf, arg_desc) else: self.help_buf.set_text("") def add_file_button_clicked_cb(self, button): if self.script_file_chooser is None: self.script_file_chooser = \ zenmapGUI.FileChoosers.ScriptFileChooserDialog( title=_("Select script files")) response = self.script_file_chooser.run() filenames = self.script_file_chooser.get_filenames() self.script_file_chooser.hide() if response != gtk.RESPONSE_OK: return for filename in filenames: self.file_liststore.append([filename, True]) if len(self.file_liststore) > 0: self.file_scrolled_window.show() self.remove_file_button.set_sensitive(True) self.set_script_from_selection() def remove_file_button_clicked_cb(self, button): selection = self.file_listview.get_selection() model, selection = selection.get_selected_rows() for path in selection: self.file_liststore.remove(model.get_iter(path)) if len(self.file_liststore) == 0: self.file_scrolled_window.hide() self.remove_file_button.set_sensitive(False) self.set_script_from_selection() def set_description(self, entry): """Sets the content that is to be displayed in the description box.""" self.text_buffer.set_text(u"") self.text_buffer.insert( self.text_buffer.get_end_iter(), """\ Categories: %(cats)s """ % {"cats": ", ".join(entry.categories)}) text_buffer_insert_nsedoc(self.text_buffer, entry.description) if entry.usage: self.text_buffer.insert(self.text_buffer.get_end_iter(), "\nUsage\n") self.text_buffer.insert_with_tags_by_name( self.text_buffer.get_end_iter(), entry.usage, "Usage") if entry.output: self.text_buffer.insert(self.text_buffer.get_end_iter(), "\nOutput\n") self.text_buffer.insert_with_tags_by_name( self.text_buffer.get_end_iter(), entry.output, "Output") if entry.url: self.text_buffer.insert(self.text_buffer.get_end_iter(), "\n" + entry.url) def populate_arg_list(self, entry): """Called when a particular script is hovered over to display its arguments and values (if any).""" self.arg_liststore.clear() self.current_arguments = [] self.value.set_property('editable', True) for arg in entry.arguments: arg_name, arg_desc = arg self.current_arguments.append(arg) value = self.arg_values.get(arg_name) if not value: self.arg_liststore.append([arg_name, None, arg]) else: self.arg_liststore.append([arg_name, value, arg])
class SearchGUI(gtk.VBox, object): """This class is a VBox that holds the search entry field and buttons on top, and the results list on the bottom. The "Cancel" and "Open" buttons are a part of the SearchWindow class, not SearchGUI.""" def __init__(self, search_window): gtk.VBox.__init__(self) self._create_widgets() self._pack_widgets() self._connect_events() # Search options self.options = {} self.options["file_extension"] = search_config.file_extension self.options["directory"] = search_config.directory self.options["search_db"] = search_config.search_db self.parsed_results = {} self._set_result_view() self.id = 0 self.search_window = search_window # The Search* objects are created once per Search Window invocation, so that # they get a list of scans only once, not whenever the search conditions change if self.options["search_db"]: self.search_db = SearchDB() # Search directories can be added via the "dir:" operator, so it needs to be a map self.search_dirs = {} self.init_search_dirs() # We create an empty search dictionary, since SearchParser will fill it # with keywords as it encounters different operators in the search string. self.search_dict = dict() self.search_parser = SearchParser(self) # This list holds the (operator, argument) tuples, parsed from the GUI criteria rows self.gui_criteria_list = [] # Do an initial "empty" search, so that the results window initially holds # all scans in the database self.search_parser.update("") self.start_search() def init_search_dirs(self, dirs=[]): # Start fresh self.search_dirs.clear() # If specified, add the search directory from the Zenmap config file to the map conf_dir = self.options["directory"] if conf_dir: self.search_dirs[conf_dir] = SearchDir( conf_dir, self.options["file_extension"]) # Process any other dirs (as added by the dir: operator) for dir in dirs: self.search_dirs[dir] = SearchDir(dir, self.options["file_extension"]) def _create_widgets(self): # Search box and buttons self.search_top_hbox = HIGHBox() self.search_label = HIGSectionLabel(_("Search:")) self.search_entry = gtk.Entry() self.expressions_btn = HIGToggleButton(_("Expressions "), gtk.STOCK_EDIT) # The quick reference tooltip button self.search_tooltip_btn = HIGButton(" ", gtk.STOCK_INFO) # The expression VBox. This is only visible once the user clicks on "Expressions" self.expr_vbox = gtk.VBox() # Results section self.result_list = gtk.ListStore(str, str, int) # title, date, id self.result_view = gtk.TreeView(self.result_list) self.result_scrolled = gtk.ScrolledWindow() self.result_title_column = gtk.TreeViewColumn(_("Scan")) self.result_date_column = gtk.TreeViewColumn(_("Date")) self.expr_window = None def _pack_widgets(self): # Packing label, search box and buttons self.search_top_hbox.set_spacing(4) self.search_top_hbox.pack_start(self.search_label, False) self.search_top_hbox.pack_start(self.search_entry, True) self.search_top_hbox.pack_start(self.expressions_btn, False) self.search_top_hbox.pack_start(self.search_tooltip_btn, False) # The expressions (if any) should be tightly packed so that they don't take # too much screen real-estate self.expr_vbox.set_spacing(0) # Packing the result section self.result_scrolled.add(self.result_view) self.result_scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) # Packing it all together self.set_spacing(4) self.pack_start(self.search_top_hbox, False) self.pack_start(self.expr_vbox, False) self.pack_start(self.result_scrolled, True) def _connect_events(self): self.search_entry.connect("changed", self.update_search_entry) self.search_tooltip_btn.connect("clicked", self.show_quick_help) self.expressions_btn.connect("toggled", self.expressions_clicked) def show_quick_help(self, widget=None, extra=None): quick_help = """Entering the text into the search performs a <b>keyword search</b> - \ the search string is matched against the entire output of each scan. To refine the search, you can use <b>operators</b> to search only within a specific part of \ a scan. Operators can be added to the search interactively if you click on the \ <b>Expressions</b> button, or you can enter them manually into the search field. \ You can also use <b>operator aliases</b> if you're an experienced user who likes to \ type in his searches quickly. <b>profile: (pr:)</b> - Profile used. <b>target: (t:)</b> - User-supplied target, or a rDNS result. <b>option: (o:)</b> - Scan options. <b>date: (d:)</b> - The date when scan was performed. Fuzzy matching is possible using the \ "~" suffix. Each "~" broadens the search by one day on "each side" of the date. In addition, \ it is possible to use the \"date:-n\" notation which means "n days ago". <b>after: (a:)</b> - Matches scans made after the supplied date (<i>YYYY-MM-DD</i> or <i>-n</i>). <b>before (b:)</b> - Matches scans made before the supplied date(<i>YYYY-MM-DD</i> or <i>-n</i>). <b>os:</b> - All OS-related fields. <b>scanned: (sp:)</b> - Matches a port if it was among those scanned. <b>open: (op:)</b> - Open ports discovered in a scan. <b>closed: (cp:)</b> - Closed ports discovered in a scan. <b>filtered: (fp:)</b> - Filtered ports discovered in scan. <b>unfiltered: (ufp:)</b> - Unfiltered ports found in a scan (using, for example, an ACK scan). <b>open|filtered: (ofp:)</b> - Ports in the \"open|filtered\" state. <b>closed|filtered: (cfp:)</b> - Ports in the \"closed|filtered\" state. <b>service: (s:)</b> - All service-related fields. <b>inroute: (ir:)</b> - Matches a router in the scan's traceroute output. """ hint_window = HintWindow(quick_help) hint_window.show_all() def expressions_clicked(self, widget=None, extra=None): if len(self.expr_vbox.get_children() ) == 0 and self.search_entry.get_text() == "": # This is the first time the user has clicked on "Show Expressions" # and the search entry box is empty, so we add a single Criterion row self.expr_vbox.pack_start(Criterion(self)) if self.expressions_btn.get_active(): # The Expressions GUI is about to be displayed. It needs to reflect all the # conditions in the search entry field, so a comparison between the entry field # and the GUI needs to be performed. # Make the search entry field insensitive while expressions are visible self.search_entry.set_sensitive(False) # Get a map of operator => argument from the Expressions GUI so that # we can compare them with the ones in the search entry field gui_ops = {} for criterion in self.expr_vbox.get_children(): if criterion.operator in gui_ops: gui_ops[criterion.operator].append(criterion.argument) else: gui_ops[criterion.operator] = [criterion.argument] # We compare the search entry field to the Expressions GUI. Every # (operator, value) pair must be present in the GUI after this loop is done. for op, args in self.search_dict.iteritems(): for arg in args: if (op not in gui_ops) or (arg not in gui_ops[op]): # We need to add this pair to the GUI self.expr_vbox.pack_start(Criterion(self, op, arg), False) # Now we check if there are any leftover criterion rows that aren't present # in the search_dict (for example, if a user has deleted something from the # search entry field) for criterion in self.expr_vbox.get_children(): if criterion.operator not in self.search_dict or \ criterion.argument not in self.search_dict[criterion.operator]: criterion.destroy() # If we have deleted all rows, add an empty one if len(self.expr_vbox.get_children()) == 0: self.expr_vbox.pack_start(Criterion(self)) # Display all elements self.expr_vbox.show_all() else: # The Expressions GUI is about to be hidden. No updates to the search entry field # are necessary, since it gets updated on every change in one of the criterion rows. self.expr_vbox.hide_all() self.search_entry.set_sensitive(True) def close(self): if self.expr_window != None: self.expr_window.close() def add_criterion(self, caller): # We need to find where the caller (Criteria object) is located among # all the rows, so that we can insert the new row after it caller_index = self.expr_vbox.get_children().index(caller) # Make a new Criteria row and insert it after the calling row criteria = Criterion(self, "keyword") self.expr_vbox.pack_start(criteria, False) self.expr_vbox.reorder_child(criteria, caller_index + 1) criteria.show_all() def remove_criterion(self, c): if len(self.expr_vbox.get_children()) > 1: c.destroy() self.criterion_changed() def criterion_changed(self): # We go through all criteria rows and make a new search string search_string = "" for criterion in self.expr_vbox.get_children(): if criterion.operator != "keyword": search_string += criterion.operator + ":" search_string += criterion.argument.replace(" ", "") + " " self.search_entry.set_text(search_string.strip()) self.search_parser.update(self.search_entry.get_text()) self.start_search() def add_search_dir(self, dir): if dir not in self.search_dirs: self.search_dirs[dir] = SearchDir(dir, self.options["file_extension"]) def update_search_entry(self, widget, extra=None): """Called when the search entry field is modified.""" self.search_parser.update(widget.get_text()) self.start_search() def start_search(self): if not self.options["search_db"] and not self.options["directory"]: d = HIGAlertDialog( message_format=_("No search method selected!"), secondary_text=_("%s can search results on directories or \ inside it's own database. Please, select a method by choosing a directory or by checking \ the search data base option at the 'Search options' tab before start the search" % APP_DISPLAY_NAME)) d.run() d.destroy() return self.clear_result_list() matched = 0 total = 0 if self.options["search_db"]: total += len(self.search_db.get_scan_results()) for result in self.search_db.search(**self.search_dict): self.append_result(result) matched += 1 for search_dir in self.search_dirs.itervalues(): total += len(search_dir.get_scan_results()) for result in search_dir.search(**self.search_dict): self.append_result(result) matched += 1 #total += len(self.search_tabs.get_scan_results()) #for result in self.search_tabs.search(**self.search_dict): # self.append_result(result) # matched += 1 self.search_window.set_label_text("Matched <b>%s</b> out of <b>%s</b> scans." % \ (str(matched), str(total))) def clear_result_list(self): for i in range(len(self.result_list)): iter = self.result_list.get_iter_root() del (self.result_list[iter]) def append_result(self, parsed_result): title = "" if parsed_result.scan_name: title = parsed_result.scan_name elif parsed_result.filename: title = os.path.split(parsed_result.filename)[-1] elif parsed_result.profile_name and parsed_result.target: title = "%s on %s" % (parsed_result.profile_name, parsed_result.target) else: title = parsed_result.get_nmap_command() try: date = localtime(float(parsed_result.start)) #date_field = "%02d %s %04d" % (date[2], months[date[1]][:3], date[0]) date_field = "%04d-%02d-%02d %02d:%02d" % ( date[0], date[1], date[2], date[3], date[4]) except ValueError: date_field = _("Unknown") self.parsed_results[self.id] = [title, parsed_result] self.result_list.append([title, date_field, self.id]) self.id += 1 def get_selected_results(self): selection = self.result_view.get_selection() rows = selection.get_selected_rows() list_store = rows[0] results = {} for row in rows[1]: r = row[0] results[list_store[r][2]] = self.parsed_results[list_store[r][2]] return results def _set_result_view(self): self.result_view.set_enable_search(True) self.result_view.set_search_column(0) selection = self.result_view.get_selection() selection.set_mode(gtk.SELECTION_MULTIPLE) self.result_view.append_column(self.result_title_column) self.result_view.append_column(self.result_date_column) self.result_title_column.set_resizable(True) self.result_title_column.set_min_width(200) self.result_date_column.set_resizable(True) self.result_title_column.set_sort_column_id(0) self.result_date_column.set_sort_column_id(1) self.result_title_column.set_reorderable(True) self.result_date_column.set_reorderable(True) cell = gtk.CellRendererText() self.result_title_column.pack_start(cell, True) self.result_date_column.pack_start(cell, True) self.result_title_column.set_attributes(cell, text=0) self.result_date_column.set_attributes(cell, text=1) selected_results = property(get_selected_results)
class UmitCredits(HIGWindow): def __init__(self): HIGWindow.__init__(self) self.set_title(_("%s credits") % UMIT_DISPLAY_NAME) self.set_size_request(-1, 250) self.set_position(gtk.WIN_POS_CENTER) self.__create_widgets() self.__packing() self.set_text() def __create_widgets(self): self.vbox = HIGVBox() self.hbox = HIGHBox() self.notebook = HIGNotebook() self.btn_close = HIGButton(stock=gtk.STOCK_CLOSE) self.written_by_scroll = HIGScrolledWindow() self.written_by_text = HIGTextView() self.design_scroll = HIGScrolledWindow() self.design_text = HIGTextView() self.soc2007_scroll = HIGScrolledWindow() self.soc2007_text = HIGTextView() self.contributors_scroll = HIGScrolledWindow() self.contributors_text = HIGTextView() self.translation_scroll = HIGScrolledWindow() self.translation_text = HIGTextView() self.nokia_scroll = HIGScrolledWindow() self.nokia_text = HIGTextView() def __packing(self): self.add(self.vbox) self.vbox.set_spacing(12) self.vbox._pack_expand_fill(self.notebook) self.vbox._pack_noexpand_nofill(self.hbox) self.hbox._pack_expand_fill(hig_box_space_holder()) self.hbox._pack_noexpand_nofill(self.btn_close) self.notebook.append_page(self.written_by_scroll, gtk.Label(_("Written by"))) self.notebook.append_page(self.design_scroll, gtk.Label(_("Design"))) self.notebook.append_page(self.soc2007_scroll, gtk.Label(_("SoC 2007"))) self.notebook.append_page(self.contributors_scroll, gtk.Label(_("Contributors"))) self.notebook.append_page(self.translation_scroll, gtk.Label(_("Translation"))) self.notebook.append_page(self.nokia_scroll, gtk.Label(_("Maemo"))) self.written_by_scroll.add(self.written_by_text) self.written_by_text.set_wrap_mode(gtk.WRAP_NONE) self.design_scroll.add(self.design_text) self.design_text.set_wrap_mode(gtk.WRAP_NONE) self.soc2007_scroll.add(self.soc2007_text) self.soc2007_text.set_wrap_mode(gtk.WRAP_NONE) self.contributors_scroll.add(self.contributors_text) self.contributors_text.set_wrap_mode(gtk.WRAP_NONE) self.translation_scroll.add(self.translation_text) self.translation_text.set_wrap_mode(gtk.WRAP_NONE) self.nokia_scroll.add(self.nokia_text) self.nokia_text.set_wrap_mode(gtk.WRAP_NONE) self.btn_close.connect('clicked', lambda x, y=None: self.destroy()) def set_text(self): b = self.written_by_text.get_buffer() b.set_text("""Adriano Monteiro Marques <*****@*****.**>""") b = self.design_text.get_buffer() b.set_text("""Operating System and Vulnerability Icons: Takeshi Alexandre Gondo <*****@*****.**> Logo, Application Icons and Splash screen: Virgílio Carlo de Menezes Vasconcelos <*****@*****.**> The Umit Project Web Site Design: Joao Paulo Pacheco <*****@*****.**>""") b = self.soc2007_text.get_buffer() b.set_text("""Independent Features: Adriano Monteiro Marques <*****@*****.**> Frederico Silva Ribeiro <*****@*****.**> Network Inventory: Guilherme Henrique Polo Gonçalves <*****@*****.**> Umit Radial Mapper: João Paulo de Souza Medeiros <*****@*****.**> Profile/Wizard interface editor: Luis Antonio Bastião Silva <*****@*****.**> NSE Facilitator: Maxim I. Gavrilov <*****@*****.**> Umit Web: Rodolfo da Silva Carvalho <*****@*****.**>""") b = self.contributors_text.get_buffer() b.set_text("""Sponsored by (SoC 2005, 2006 and 2007): Google <*****@*****.**> Mentor of Umit for Google SoC 2005 and 2006: Fyodor <*****@*****.**> Mentor of Umit for Google SoC 2007 Projects: Adriano Monteiro Marques <*****@*****.**> Initial development: Adriano Monteiro Marques <*****@*****.**> Cleber Rodrigues Rosa Junior <*****@*****.**> Nmap students from Google SoC 2007 that helped Umit: Eddie Bell <*****@*****.**> David Fifield <*****@*****.**> Kris Katterjohn <*****@*****.**> The Umit Project WebSite: AbraoBarbosa dos Santos Neto <*****@*****.**> Adriano Monteiro Marques <*****@*****.**> Heitor de Lima Matos <*****@*****.**> Joao Paulo Pacheco <*****@*****.**> João Paulo de Souza Medeiros <*****@*****.**> Luis Antonio Bastião Silva <*****@*****.**> Rodolfo da Silva Carvalho <*****@*****.**> Beta testers for 0.9.5RC1: Drew Miller <*****@*****.**> Igor Feghali <*****@*****.**> Joao Paulo Pacheco <*****@*****.**> Luis Antonio Bastião Silva <*****@*****.**> <*****@*****.**> <*****@*****.**> <*****@*****.**> Initial attempt on Maemo port: Adriano Monteiro Marques <*****@*****.**> Osvaldo Santana Neto <*****@*****.**>""") b = self.translation_text.get_buffer() b.set_text("""Brazilian Portuguese: Adriano Monteiro Marques <*****@*****.**>""") b = self.nokia_text.get_buffer() b.set_text("""Adriano Monteiro Marques <*****@*****.**>""")
class ProfileEditor(HIGWindow): def __init__(self, command=None, profile_name=None, deletable=True, overwrite=False): HIGWindow.__init__(self) self.connect("delete_event", self.exit) self.set_title(_('Profile Editor')) self.set_position(gtk.WIN_POS_CENTER) self.deletable = deletable self.profile_name = profile_name self.overwrite = overwrite # Used to block recursive updating of the command entry when the # command entry causes the OptionBuilder widgets to change. self.inhibit_command_update = False self.__create_widgets() self.__pack_widgets() self.profile = CommandProfile() self.ops = NmapOptions() if profile_name: log.debug("Showing profile %s" % profile_name) prof = self.profile.get_profile(profile_name) # Interface settings self.profile_name_entry.set_text(profile_name) self.profile_description_text.get_buffer().set_text( prof['description']) command_string = prof['command'] self.ops.parse_string(command_string) if command: self.ops.parse_string(command) self.option_builder = OptionBuilder( Path.profile_editor, self.ops, self.update_command, self.help_field.get_buffer()) log.debug("Option groups: %s" % str(self.option_builder.groups)) log.debug("Option section names: %s" % str( self.option_builder.section_names)) #log.debug("Option tabs: %s" % str(self.option_builder.tabs)) for tab in self.option_builder.groups: self.__create_tab( _(tab), _(self.option_builder.section_names[tab]), self.option_builder.tabs[tab]) self.update_command() def command_entry_changed_cb(self, widget): command_string = self.command_entry.get_text().decode("UTF-8") self.ops.parse_string(command_string) self.inhibit_command_update = True self.option_builder.update() self.inhibit_command_update = False def update_command(self): """Regenerate and display the command.""" if not self.inhibit_command_update: # Block recursive updating of the OptionBuilder widgets when they # cause a change in the command entry. self.command_entry.handler_block(self.command_entry_changed_cb_id) self.command_entry.set_text(self.ops.render_string()) self.command_entry.handler_unblock( self.command_entry_changed_cb_id) def update_help_name(self, widget, extra): self.help_field.get_buffer().set_text( "Profile name\n\nThis is how the profile will be identified " "in the drop-down combo box in the scan tab.") def update_help_desc(self, widget, extra): self.help_field.get_buffer().set_text( "Description\n\nThe description is a full description of what " "the scan does, which may be long.") def __create_widgets(self): ### # Vertical box to keep 3 boxes self.main_whole_box = HIGVBox() self.upper_box = HIGHBox() self.middle_box = HIGHBox() self.lower_box = HIGHBox() #self.main_vbox = HIGVBox() self.command_entry = gtk.Entry() self.command_entry_changed_cb_id = self.command_entry.connect( "changed", self.command_entry_changed_cb) self.scan_button = HIGButton(_("Scan")) self.scan_button.connect("clicked", self.run_scan) self.notebook = gtk.Notebook() # Profile info page self.profile_info_vbox = HIGVBox() self.profile_info_label = HIGSectionLabel(_('Profile Information')) self.profile_name_label = HIGEntryLabel(_('Profile name')) self.profile_name_entry = gtk.Entry() self.profile_name_entry.connect( 'enter-notify-event', self.update_help_name) self.profile_description_label = HIGEntryLabel(_('Description')) self.profile_description_scroll = HIGScrolledWindow() self.profile_description_scroll.set_border_width(0) self.profile_description_text = HIGTextView() self.profile_description_text.connect( 'motion-notify-event', self.update_help_desc) # Buttons self.buttons_hbox = HIGHBox() self.cancel_button = HIGButton(stock=gtk.STOCK_CANCEL) self.cancel_button.connect('clicked', self.exit) self.delete_button = HIGButton(stock=gtk.STOCK_DELETE) self.delete_button.connect('clicked', self.delete_profile) self.save_button = HIGButton(_("Save Changes"), stock=gtk.STOCK_SAVE) self.save_button.connect('clicked', self.save_profile) ### self.help_vbox = HIGVBox() self.help_label = HIGSectionLabel(_('Help')) self.help_scroll = HIGScrolledWindow() self.help_scroll.set_border_width(0) self.help_field = HIGTextView() self.help_field.set_cursor_visible(False) self.help_field.set_left_margin(5) self.help_field.set_editable(False) self.help_vbox.set_size_request(200, -1) ### def __pack_widgets(self): ### self.add(self.main_whole_box) # Packing command entry to upper box self.upper_box._pack_expand_fill(self.command_entry) self.upper_box._pack_noexpand_nofill(self.scan_button) # Packing notebook (left) and help box (right) to middle box self.middle_box._pack_expand_fill(self.notebook) self.middle_box._pack_expand_fill(self.help_vbox) # Packing buttons to lower box self.lower_box.pack_end(self.buttons_hbox) # Packing the three vertical boxes to the main box self.main_whole_box._pack_noexpand_nofill(self.upper_box) self.main_whole_box._pack_expand_fill(self.middle_box) self.main_whole_box._pack_noexpand_nofill(self.lower_box) ### # Packing profile information tab on notebook self.notebook.append_page( self.profile_info_vbox, gtk.Label(_('Profile'))) self.profile_info_vbox.set_border_width(5) table = HIGTable() self.profile_info_vbox._pack_noexpand_nofill(self.profile_info_label) self.profile_info_vbox._pack_expand_fill(HIGSpacer(table)) self.profile_description_scroll.add(self.profile_description_text) vbox_desc = HIGVBox() vbox_desc._pack_noexpand_nofill(self.profile_description_label) vbox_desc._pack_expand_fill(hig_box_space_holder()) vbox_ann = HIGVBox() vbox_ann._pack_expand_fill(hig_box_space_holder()) table.attach( self.profile_name_label, 0, 1, 0, 1, xoptions=0, yoptions=0) table.attach(self.profile_name_entry, 1, 2, 0, 1, yoptions=0) table.attach(vbox_desc, 0, 1, 1, 2, xoptions=0) table.attach(self.profile_description_scroll, 1, 2, 1, 2) # Packing buttons on button_hbox self.buttons_hbox._pack_expand_fill(hig_box_space_holder()) if self.deletable: self.buttons_hbox._pack_noexpand_nofill(self.delete_button) self.buttons_hbox._pack_noexpand_nofill(self.cancel_button) self.buttons_hbox._pack_noexpand_nofill(self.save_button) self.buttons_hbox.set_border_width(5) self.buttons_hbox.set_spacing(6) ### self.help_vbox._pack_noexpand_nofill(self.help_label) self.help_vbox._pack_expand_fill(self.help_scroll) self.help_scroll.add(self.help_field) self.help_vbox.set_border_width(1) self.help_vbox.set_spacing(1) ### def __create_tab(self, tab_name, section_name, tab): log.debug(">>> Tab name: %s" % tab_name) log.debug(">>>Creating profile editor section: %s" % section_name) vbox = HIGVBox() if tab.notscripttab: # if notscripttab is set table = HIGTable() table.set_row_spacings(2) section = HIGSectionLabel(section_name) vbox._pack_noexpand_nofill(section) vbox._pack_noexpand_nofill(HIGSpacer(table)) vbox.set_border_width(5) tab.fill_table(table, True) else: hbox = tab.get_hmain_box() vbox.pack_start(hbox, True, True, 0) self.notebook.append_page(vbox, gtk.Label(tab_name)) def save_profile(self, widget): if self.overwrite: self.profile.remove_profile(self.profile_name) profile_name = self.profile_name_entry.get_text() if profile_name == '': alert = HIGAlertDialog( message_format=_('Unnamed profile'), secondary_text=_( 'You must provide a name for this profile.')) alert.run() alert.destroy() self.profile_name_entry.grab_focus() return None command = self.ops.render_string() buf = self.profile_description_text.get_buffer() description = buf.get_text( buf.get_start_iter(), buf.get_end_iter()) try: self.profile.add_profile( profile_name, command=command, description=description) except ValueError: alert = HIGAlertDialog( message_format=_('Disallowed profile name'), secondary_text=_('Sorry, the name "%s" is not allowed due ' 'to technical limitations. (The underlying ' 'ConfigParser used to store profiles does not allow ' 'it.) Choose a different name.' % profile_name)) alert.run() alert.destroy() return self.scan_interface.toolbar.profile_entry.update() self.destroy() def clean_profile_info(self): self.profile_name_entry.set_text('') self.profile_description_text.get_buffer().set_text('') def set_scan_interface(self, interface): self.scan_interface = interface def exit(self, *args): self.destroy() def delete_profile(self, widget=None, extra=None): if self.deletable: dialog = HIGDialog(buttons=(gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)) alert = HIGEntryLabel('<b>' + _("Deleting Profile") + '</b>') text = HIGEntryLabel(_( 'Your profile is going to be deleted! ClickOk to continue, ' 'or Cancel to go back to Profile Editor.')) hbox = HIGHBox() hbox.set_border_width(5) hbox.set_spacing(12) vbox = HIGVBox() vbox.set_border_width(5) vbox.set_spacing(12) image = gtk.Image() image.set_from_stock( gtk.STOCK_DIALOG_WARNING, gtk.ICON_SIZE_DIALOG) vbox.pack_start(alert) vbox.pack_start(text) hbox.pack_start(image) hbox.pack_start(vbox) dialog.vbox.pack_start(hbox) dialog.vbox.show_all() response = dialog.run() dialog.destroy() if response == gtk.RESPONSE_CANCEL: return True self.profile.remove_profile(self.profile_name) self.update_profile_entry() self.destroy() def run_scan(self, widget=None): command_string = self.command_entry.get_text().decode("UTF-8") self.scan_interface.command_toolbar.command = command_string self.scan_interface.start_scan_cb() self.exit() def update_profile_entry(self, widget=None, extra=None): self.scan_interface.toolbar.profile_entry.update() list = self.scan_interface.toolbar.profile_entry.get_model() length = len(list) if length > 0: self.scan_interface.toolbar.profile_entry.set_active(0)
class DiffWindow(gtk.Window): def __init__(self, scans): gtk.Window.__init__(self) self.set_title(_("Compare Results")) self.ndiff_process = None # We allow the user to start a new diff before the old one has # finished. We have to keep references to old processes until they # finish to avoid problems when tearing down the Python interpreter at # program exit. self.old_processes = [] self.timer_id = None self.main_vbox = HIGVBox() self.diff_view = DiffView() self.diff_view.set_size_request(-1, 100) self.hbox_buttons = HIGHBox() self.progress = gtk.ProgressBar() self.btn_close = HIGButton(stock=gtk.STOCK_CLOSE) self.hbox_selection = HIGHBox() self.scan_chooser_a = ScanChooser(scans, _(u"A Scan")) self.scan_chooser_b = ScanChooser(scans, _(u"B Scan")) self._pack_widgets() self._connect_widgets() self.set_default_size(-1, 500) # Initial Size Request self.initial_size = self.get_size() def _pack_widgets(self): self.main_vbox.set_border_width(6) self.hbox_selection.pack_start(self.scan_chooser_a, True, True) self.hbox_selection.pack_start(self.scan_chooser_b, True, True) self.main_vbox.pack_start(self.hbox_selection, False) scroll = gtk.ScrolledWindow() scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scroll.add(self.diff_view) self.main_vbox.pack_start(scroll, True, True) self.progress.hide() self.progress.set_no_show_all(True) self.hbox_buttons.pack_start(self.progress, False) self.hbox_buttons.pack_end(self.btn_close, False) self.main_vbox._pack_noexpand_nofill(self.hbox_buttons) self.add(self.main_vbox) def _connect_widgets(self): self.connect("delete-event", self.close) self.btn_close.connect("clicked", self.close) self.scan_chooser_a.connect('changed', self.refresh_diff) self.scan_chooser_b.connect('changed', self.refresh_diff) def refresh_diff(self, widget): """This method is called whenever the diff output might have changed, such as when a different scan was selected in one of the choosers.""" log.debug("Refresh diff.") if (self.ndiff_process is not None and self.ndiff_process.poll() is None): # Put this in the list of old processes we keep track of. self.old_processes.append(self.ndiff_process) self.ndiff_process = None scan_a = self.scan_chooser_a.parsed_scan scan_b = self.scan_chooser_b.parsed_scan if scan_a is None or scan_b is None: self.diff_view.clear() else: try: self.ndiff_process = zenmapCore.Diff.ndiff(scan_a, scan_b) except OSError, e: alert = HIGAlertDialog( message_format=_("Error running ndiff"), secondary_text=_( "There was an error running the ndiff program.\n\n" ) + str(e).decode(sys.getdefaultencoding(), "replace")) alert.run() alert.destroy() else:
def make_script_list_widget(self): """Creates and packs widgets associated with left hand side of Interface.""" vbox = gtk.VBox() scrolled_window = HIGScrolledWindow() scrolled_window.set_policy(gtk.POLICY_ALWAYS, gtk.POLICY_ALWAYS) # Expand only vertically. scrolled_window.set_size_request(175, -1) listview = gtk.TreeView(self.liststore) listview.set_headers_visible(False) listview.connect("enter-notify-event", self.update_help_ls_cb) selection = listview.get_selection() selection.connect("changed", self.selection_changed_cb) cell = gtk.CellRendererText() togglecell = gtk.CellRendererToggle() togglecell.set_property("activatable", True) togglecell.connect("toggled", self.toggled_cb, self.liststore) col = gtk.TreeViewColumn(_('Names')) col.set_sizing(gtk.TREE_VIEW_COLUMN_GROW_ONLY) col.set_resizable(True) togglecol = gtk.TreeViewColumn(None, togglecell) togglecol.add_attribute(togglecell, "active", 1) listview.append_column(togglecol) listview.append_column(col) col.pack_start(cell, True) col.add_attribute(cell, "text", 0) scrolled_window.add(listview) scrolled_window.show() vbox.pack_start(scrolled_window, True, True, 0) self.file_scrolled_window = HIGScrolledWindow() self.file_scrolled_window.set_policy(gtk.POLICY_ALWAYS, gtk.POLICY_ALWAYS) self.file_scrolled_window.set_size_request(175, -1) self.file_scrolled_window.hide() self.file_scrolled_window.set_no_show_all(True) self.file_listview = gtk.TreeView(self.file_liststore) self.file_listview.set_headers_visible(False) col = gtk.TreeViewColumn(None) self.file_listview.append_column(col) cell = gtk.CellRendererToggle() col.pack_start(cell, True) cell.set_property("activatable", True) col.add_attribute(cell, "active", 1) cell.connect("toggled", self.toggled_cb, self.file_liststore) col = gtk.TreeViewColumn(None) self.file_listview.append_column(col) cell = gtk.CellRendererText() col.pack_start(cell) col.add_attribute(cell, "text", 0) self.file_listview.show_all() self.file_scrolled_window.add(self.file_listview) vbox.pack_start(self.file_scrolled_window, False) hbox = HIGHBox(False, 2) self.remove_file_button = HIGButton(stock=gtk.STOCK_REMOVE) self.remove_file_button.connect("clicked", self.remove_file_button_clicked_cb) self.remove_file_button.set_sensitive(False) hbox.pack_end(self.remove_file_button) add_file_button = HIGButton(stock=gtk.STOCK_ADD) add_file_button.connect("clicked", self.add_file_button_clicked_cb) hbox.pack_end(add_file_button) vbox.pack_start(hbox, False, False, 0) return vbox
class ScanScanListPage(HIGVBox): """This is the "Scans" scan results tab. It the list of running and finished scans contained in the ScansListStore passed to the constructor.""" def __init__(self, scans_store): HIGVBox.__init__(self) self.set_spacing(4) scans_store.connect("row-changed", self._row_changed) self.scans_list = gtk.TreeView(scans_store) self.scans_list.get_selection().connect("changed", self._selection_changed) status_col = gtk.TreeViewColumn(_("Status")) cell = gtk.CellRendererText() status_col.pack_start(cell) status_col.set_cell_data_func(cell, status_data_func) self.scans_list.append_column(status_col) command_col = gtk.TreeViewColumn(_("Command")) cell = gtk.CellRendererText() command_col.pack_start(cell) command_col.set_cell_data_func(cell, command_data_func) self.scans_list.append_column(command_col) scrolled_window = HIGScrolledWindow() scrolled_window.set_border_width(0) scrolled_window.add(self.scans_list) self.pack_start(scrolled_window, True, True) hbox = HIGHBox() buttonbox = gtk.HButtonBox() buttonbox.set_layout(gtk.BUTTONBOX_START) buttonbox.set_spacing(4) self.append_button = HIGButton(_("Append Scan"), gtk.STOCK_ADD) buttonbox.pack_start(self.append_button, False) self.remove_button = HIGButton(_("Remove Scan"), gtk.STOCK_REMOVE) buttonbox.pack_start(self.remove_button, False) self.cancel_button = HIGButton(_("Cancel Scan"), gtk.STOCK_CANCEL) buttonbox.pack_start(self.cancel_button, False) hbox.pack_start(buttonbox, padding = 4) self.pack_start(hbox, False, padding = 4) self._update() def _row_changed(self, model, path, i): self._update() def _selection_changed(self, selection): self._update() def _update(self): # Make the Cancel button sensitive or not depending on whether a running # scan is selected. tree_selection = self.scans_list.get_selection() if tree_selection is None: # I can't find anything in the PyGTK documentation that suggests # this is possible, but we received many crash reports that indicate # it is. model, selection = None, [] else: model, selection = tree_selection.get_selected_rows() for path in selection: entry = model.get_value(model.get_iter(path), 0) if entry.running: self.cancel_button.set_sensitive(True) break else: self.cancel_button.set_sensitive(False) if len(selection) == 0: self.remove_button.set_sensitive(False) else: self.remove_button.set_sensitive(True)
class ScanScanListPage(HIGVBox): """This is the "Scans" scan results tab. It the list of running and finished scans contained in the ScansListStore passed to the constructor.""" def __init__(self, scans_store): HIGVBox.__init__(self) self.set_spacing(4) scans_store.connect("row-changed", self._row_changed) self.scans_list = gtk.TreeView(scans_store) self.scans_list.get_selection().connect("changed", self._selection_changed) status_col = gtk.TreeViewColumn(_("Status")) cell = gtk.CellRendererText() status_col.pack_start(cell) status_col.set_cell_data_func(cell, status_data_func) self.scans_list.append_column(status_col) command_col = gtk.TreeViewColumn(_("Command")) cell = gtk.CellRendererText() command_col.pack_start(cell) command_col.set_cell_data_func(cell, command_data_func) self.scans_list.append_column(command_col) scrolled_window = HIGScrolledWindow() scrolled_window.set_border_width(0) scrolled_window.add(self.scans_list) self.pack_start(scrolled_window, True, True) hbox = HIGHBox() buttonbox = gtk.HButtonBox() buttonbox.set_layout(gtk.BUTTONBOX_START) buttonbox.set_spacing(4) self.append_button = HIGButton(_("Append Scan"), gtk.STOCK_ADD) buttonbox.pack_start(self.append_button, False) self.remove_button = HIGButton(_("Remove Scan"), gtk.STOCK_REMOVE) buttonbox.pack_start(self.remove_button, False) self.cancel_button = HIGButton(_("Cancel Scan"), gtk.STOCK_CANCEL) buttonbox.pack_start(self.cancel_button, False) hbox.pack_start(buttonbox, padding=4) self.pack_start(hbox, False, padding=4) self._update() def _row_changed(self, model, path, i): self._update() def _selection_changed(self, selection): self._update() def _update(self): # Make the Cancel button sensitive or not depending on whether a # running scan is selected. tree_selection = self.scans_list.get_selection() if tree_selection is None: # I can't find anything in the PyGTK documentation that suggests # this is possible, but we received many crash reports that # indicate it is. model, selection = None, [] else: model, selection = tree_selection.get_selected_rows() for path in selection: entry = model.get_value(model.get_iter(path), 0) if entry.running: self.cancel_button.set_sensitive(True) break else: self.cancel_button.set_sensitive(False) if len(selection) == 0: self.remove_button.set_sensitive(False) else: self.remove_button.set_sensitive(True)
class SearchGUI(gtk.VBox, object): """This class is a VBox that holds the search entry field and buttons on top, and the results list on the bottom. The "Cancel" and "Open" buttons are a part of the SearchWindow class, not SearchGUI.""" def __init__(self, search_window): gtk.VBox.__init__(self) self._create_widgets() self._pack_widgets() self._connect_events() # Search options self.options = {} self.options["file_extension"] = search_config.file_extension self.options["directory"] = search_config.directory self.options["search_db"] = search_config.search_db self.parsed_results = {} self._set_result_view() self.id = 0 self.search_window = search_window # The Search* objects are created once per Search Window invocation, so # that they get a list of scans only once, not whenever the search # conditions change if self.options["search_db"]: try: self.search_db = SearchDB() except ImportError as e: self.search_db = SearchDummy() self.no_db_warning.show() self.no_db_warning.set_text( 'Warning: The database of saved scans is not ' 'available. (%s.) Use "Include Directory" under ' '"Expressions" to search a directory.' % str(e)) # Search directories can be added via the "dir:" operator, so it needs # to be a map self.search_dirs = {} self.init_search_dirs() # We create an empty search dictionary, since SearchParser will fill it # with keywords as it encounters different operators in the search # string. self.search_dict = dict() # We need to define our own keyword search dictionary search_keywords = dict() search_keywords["keyword"] = "keyword" search_keywords["profile"] = "profile" search_keywords["pr"] = "profile" search_keywords["target"] = "target" search_keywords["t"] = "target" search_keywords["option"] = "option" search_keywords["o"] = "option" search_keywords["date"] = "date" search_keywords["d"] = "date" search_keywords["after"] = "after" search_keywords["a"] = "after" search_keywords["before"] = "before" search_keywords["b"] = "before" search_keywords["os"] = "os" search_keywords["scanned"] = "scanned" search_keywords["sp"] = "scanned" search_keywords["open"] = "open" search_keywords["op"] = "open" search_keywords["closed"] = "closed" search_keywords["cp"] = "closed" search_keywords["filtered"] = "filtered" search_keywords["fp"] = "filtered" search_keywords["unfiltered"] = "unfiltered" search_keywords["ufp"] = "unfiltered" search_keywords["open|filtered"] = "open_filtered" search_keywords["ofp"] = "open_filtered" search_keywords["closed|filtered"] = "closed_filtered" search_keywords["cfp"] = "closed_filtered" search_keywords["service"] = "service" search_keywords["s"] = "service" search_keywords["inroute"] = "in_route" search_keywords["ir"] = "in_route" self.search_parser = SearchParser(self, search_keywords) # This list holds the (operator, argument) tuples, parsed from the GUI # criteria rows self.gui_criteria_list = [] # Do an initial "empty" search, so that the results window initially # holds all scans in the database self.search_parser.update("") self.start_search() def init_search_dirs(self, dirs=[]): # Start fresh self.search_dirs.clear() # If specified, add the search directory from the Zenmap config file to # the map conf_dir = self.options["directory"] if conf_dir: self.search_dirs[conf_dir] = SearchDir( conf_dir, self.options["file_extension"]) # Process any other dirs (as added by the dir: operator) for dir in dirs: self.search_dirs[dir] = SearchDir(dir, self.options["file_extension"]) def _create_widgets(self): # Search box and buttons self.search_top_hbox = HIGHBox() self.search_label = HIGSectionLabel(_("Search:")) self.search_entry = gtk.Entry() self.expressions_btn = HIGToggleButton(_("Expressions "), gtk.STOCK_EDIT) # The quick reference tooltip button self.search_tooltip_btn = HIGButton(" ", gtk.STOCK_INFO) # The expression VBox. This is only visible once the user clicks on # "Expressions" self.expr_vbox = gtk.VBox() # Results section self.result_list = gtk.ListStore(str, str, int) # title, date, id self.result_view = gtk.TreeView(self.result_list) self.result_scrolled = gtk.ScrolledWindow() self.result_title_column = gtk.TreeViewColumn(_("Scan")) self.result_date_column = gtk.TreeViewColumn(_("Date")) self.no_db_warning = gtk.Label() self.no_db_warning.set_line_wrap(True) self.no_db_warning.set_no_show_all(True) self.expr_window = None def _pack_widgets(self): # Packing label, search box and buttons self.search_top_hbox.set_spacing(4) self.search_top_hbox.pack_start(self.search_label, False) self.search_top_hbox.pack_start(self.search_entry, True) self.search_top_hbox.pack_start(self.expressions_btn, False) self.search_top_hbox.pack_start(self.search_tooltip_btn, False) # The expressions (if any) should be tightly packed so that they don't # take too much screen real-estate self.expr_vbox.set_spacing(0) # Packing the result section self.result_scrolled.add(self.result_view) self.result_scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) # Packing it all together self.set_spacing(4) self.pack_start(self.search_top_hbox, False) self.pack_start(self.expr_vbox, False) self.pack_start(self.result_scrolled, True) self.pack_start(self.no_db_warning, False) def _connect_events(self): self.search_entry.connect("changed", self.update_search_entry) self.search_tooltip_btn.connect("clicked", self.show_quick_help) self.expressions_btn.connect("toggled", self.expressions_clicked) def show_quick_help(self, widget=None, extra=None): hint_window = HintWindow(QUICK_HELP_TEXT) hint_window.show_all() def expressions_clicked(self, widget=None, extra=None): if (len(self.expr_vbox.get_children()) == 0 and self.search_entry.get_text() == ""): # This is the first time the user has clicked on "Show Expressions" # and the search entry box is empty, so we add a single Criterion # row self.expr_vbox.pack_start(Criterion(self)) if self.expressions_btn.get_active(): # The Expressions GUI is about to be displayed. It needs to reflect # all the conditions in the search entry field, so a comparison # between the entry field and the GUI needs to be performed. # Make the search entry field insensitive while expressions are # visible self.search_entry.set_sensitive(False) # Get a map of operator => argument from the Expressions GUI so # that we can compare them with the ones in the search entry field gui_ops = {} for criterion in self.expr_vbox.get_children(): if criterion.operator in gui_ops: gui_ops[criterion.operator].append(criterion.argument) else: gui_ops[criterion.operator] = [criterion.argument] # We compare the search entry field to the Expressions GUI. Every # (operator, value) pair must be present in the GUI after this loop # is done. for op, args in six.iteritems(self.search_dict): for arg in args: if (op not in gui_ops) or (arg not in gui_ops[op]): # We need to add this pair to the GUI self.expr_vbox.pack_start(Criterion(self, op, arg), False) # Now we check if there are any leftover criterion rows that aren't # present in the search_dict (for example, if a user has deleted # something from the search entry field) for criterion in self.expr_vbox.get_children(): if (criterion.operator not in self.search_dict or criterion.argument not in self.search_dict[criterion.operator]): criterion.destroy() # If we have deleted all rows, add an empty one if len(self.expr_vbox.get_children()) == 0: self.expr_vbox.pack_start(Criterion(self)) # Display all elements self.expr_vbox.show_all() else: # The Expressions GUI is about to be hidden. No updates to the # search entry field are necessary, since it gets updated on every # change in one of the criterion rows. self.expr_vbox.hide_all() self.search_entry.set_sensitive(True) def close(self): if self.expr_window is not None: self.expr_window.close() def add_criterion(self, caller): # We need to find where the caller (Criteria object) is located among # all the rows, so that we can insert the new row after it caller_index = self.expr_vbox.get_children().index(caller) # Make a new Criteria row and insert it after the calling row criteria = Criterion(self, "keyword") self.expr_vbox.pack_start(criteria, False) self.expr_vbox.reorder_child(criteria, caller_index + 1) criteria.show_all() def remove_criterion(self, c): if len(self.expr_vbox.get_children()) > 1: c.destroy() self.criterion_changed() def criterion_changed(self): # We go through all criteria rows and make a new search string search_string = "" for criterion in self.expr_vbox.get_children(): if criterion.operator != "keyword": search_string += criterion.operator + ":" search_string += criterion.argument.replace(" ", "") + " " self.search_entry.set_text(search_string.strip()) self.search_parser.update(self.search_entry.get_text()) self.start_search() def add_search_dir(self, dir): if dir not in self.search_dirs: self.search_dirs[dir] = SearchDir(dir, self.options["file_extension"]) def update_search_entry(self, widget, extra=None): """Called when the search entry field is modified.""" self.search_parser.update(widget.get_text()) self.start_search() def start_search(self): if not self.options["search_db"] and not self.options["directory"]: d = HIGAlertDialog( message_format=_("No search method selected!"), secondary_text=_( "%s can search results on directories or inside its " "own database. Please select a method by choosing a " "directory or by checking the search data base option " "in the 'Search options' tab before starting a search") % APP_DISPLAY_NAME) d.run() d.destroy() return self.clear_result_list() matched = 0 total = 0 if self.options["search_db"]: total += len(self.search_db.get_scan_results()) for result in self.search_db.search(**self.search_dict): self.append_result(result) matched += 1 for search_dir in six.itervalues(self.search_dirs): total += len(search_dir.get_scan_results()) for result in search_dir.search(**self.search_dict): self.append_result(result) matched += 1 #total += len(self.search_tabs.get_scan_results()) #for result in self.search_tabs.search(**self.search_dict): # self.append_result(result) # matched += 1 self.search_window.set_label_text( "Matched <b>%s</b> out of <b>%s</b> scans." % (str(matched), str(total))) def clear_result_list(self): for i in range(len(self.result_list)): iter = self.result_list.get_iter_root() del (self.result_list[iter]) def append_result(self, parsed_result): title = parsed_result.scan_name try: date = datetime.datetime.fromtimestamp(float(parsed_result.start)) date_field = date.strftime("%Y-%m-%d %H:%M") except ValueError: date_field = _("Unknown") self.parsed_results[self.id] = [title, parsed_result] self.result_list.append([title, date_field, self.id]) self.id += 1 def get_selected_results(self): selection = self.result_view.get_selection() rows = selection.get_selected_rows() list_store = rows[0] results = {} for row in rows[1]: r = row[0] results[list_store[r][2]] = self.parsed_results[list_store[r][2]] return results def _set_result_view(self): self.result_view.set_enable_search(True) self.result_view.set_search_column(0) selection = self.result_view.get_selection() selection.set_mode(gtk.SELECTION_MULTIPLE) self.result_view.append_column(self.result_title_column) self.result_view.append_column(self.result_date_column) self.result_title_column.set_resizable(True) self.result_title_column.set_min_width(200) self.result_date_column.set_resizable(True) self.result_title_column.set_sort_column_id(0) self.result_date_column.set_sort_column_id(1) self.result_title_column.set_reorderable(True) self.result_date_column.set_reorderable(True) cell = gtk.CellRendererText() self.result_title_column.pack_start(cell, True) self.result_date_column.pack_start(cell, True) self.result_title_column.set_attributes(cell, text=0) self.result_date_column.set_attributes(cell, text=1) selected_results = property(get_selected_results)
class DiffWindow(gtk.Window): def __init__(self, scans): """scans in the format: {"scan_title":parsed_scan} """ gtk.Window.__init__(self) self.set_title(_("Compare Results")) self.scans = scans self.umit_conf = UmitConf() self.colors = Colors() # Diff views self.text_view = DiffText(self.colors, self.umit_conf.colored_diff) self.compare_view = DiffTree(self.colors) self.temp_html_file = None self._create_widgets() self._pack_widgets() self._connect_widgets() # Settings if self.umit_conf.diff_mode == "text": self.text_mode.set_active(True) else: self.compare_mode.set_active(True) self.check_color.set_active(self.umit_conf.colored_diff) # Initial Size Request self.initial_size = self.size_request() def _show_help(self, action): webbrowser.open("file://%s" % os.path.join(Path.docs_dir, "help.html"), new=2) def _create_widgets(self): self.main_vbox = HIGVBox() self.hbox_mode = HIGHBox() self.hbox_settings = HIGHBox() self.hbox_buttons = HIGHBox() self.hbox_result = HIGHBox() self.btn_open_browser = HIGButton(_("Open in Browser"), stock=gtk.STOCK_EXECUTE) self.btn_help = HIGButton(stock=gtk.STOCK_HELP) self.btn_close = HIGButton(stock=gtk.STOCK_CLOSE) self.check_color = gtk.CheckButton(_("Enable colored diffies")) self.btn_legend = HIGButton(_("Color Descriptions"), stock=gtk.STOCK_SELECT_COLOR) self.text_mode = gtk.ToggleButton(_("Text Mode")) self.compare_mode = gtk.ToggleButton(_("Compare Mode")) self.vpaned = gtk.VPaned() self.hpaned = gtk.HPaned() self.scan_chooser1 = ScanChooser(self.scans, "1") self.scan_chooser2 = ScanChooser(self.scans, "2") self.scan_buffer1 = self.scan_chooser1.get_buffer() self.scan_buffer2 = self.scan_chooser2.get_buffer() def _pack_widgets(self): self.main_vbox.set_border_width(6) self.vpaned.pack1(self.hpaned, True, False) self.vpaned.pack2(self.hbox_result) self.hpaned.pack1(self.scan_chooser1, True, False) self.hpaned.pack2(self.scan_chooser2, True, False) self.hbox_buttons._pack_expand_fill(self.btn_help) self.hbox_buttons._pack_expand_fill(self.btn_legend) self.hbox_buttons._pack_expand_fill(self.btn_open_browser) self.hbox_buttons._pack_expand_fill(self.btn_close) self.hbox_buttons.set_homogeneous(True) self.hbox_mode.set_homogeneous(True) self.hbox_mode.pack_start(self.text_mode) self.hbox_mode.pack_start(self.compare_mode) self.hbox_settings._pack_noexpand_nofill(self.hbox_mode) self.hbox_settings._pack_expand_fill(self.check_color) self.main_vbox._pack_expand_fill(self.vpaned) self.main_vbox._pack_noexpand_nofill(self.hbox_settings) self.main_vbox._pack_noexpand_nofill(self.hbox_buttons) self.add(self.main_vbox) def _connect_widgets(self): self.connect("delete-event", self.close) self.btn_legend.connect("clicked", self.show_legend_window) self.btn_help.connect("clicked", self._show_help) self.btn_close.connect("clicked", self.close) self.btn_open_browser.connect("clicked", self.open_browser) self.check_color.connect("toggled", self._set_color) self.text_mode.connect("clicked", self._change_to_text) self.compare_mode.connect("clicked", self._change_to_compare) self.scan_chooser1.exp_scan.connect('activate', self.resize_vpane) self.scan_chooser2.exp_scan.connect('activate', self.resize_vpane) self.scan_chooser1.connect('changed', self.refresh_diff) self.scan_chooser2.connect('changed', self.refresh_diff) def open_browser(self, widget): text1 = self.scan_chooser1.nmap_output text2 = self.scan_chooser2.nmap_output if text1 is None or text2 is None: alert = HIGAlertDialog( message_format='<b>'+_('Select Scan')+'</b>', secondary_text=_("You must select two different scans to \ generate diff.")) alert.run() alert.destroy() return False if text1 == '' and text2 == '': alert = HIGAlertDialog( message_format='<b>'+_('No Text Output')+'</b>', secondary_text=_("Neither of the scans you selected has \ any text output. (Scans loaded from plain Nmap XML output files do not contain \ text output.) The HTML diff shows only differences between text output, so \ there is nothing to show.")) alert.run() alert.destroy() return False # True tells splitlines to keep line endings. text1 = text1.splitlines(True) text2 = text2.splitlines(True) if self.temp_html_file is not None: self.temp_html_file.close() # A NamedTemporaryFile is deleted when it is closed. self.temp_html_file = tempfile.NamedTemporaryFile(suffix = ".html", prefix = "zenmap-diff-") if use_html: diff = DiffHtml(text1, text2) diff = diff.generate() self.temp_html_file.write(''.join(diff)) else: diff = Diff(text1, text2) diff = diff.generate () diff.insert(0, '''<pre>(This diff is been shown in pure text \ because you dont have Python 2.4 or higher.)\n''') diff.append('</pre>') self.temp_html_file.writelines(diff) self.temp_html_file.flush() webbrowser.open("file://" + self.temp_html_file.name, autoraise=1) def show_legend_window(self, widget): legend_window = DiffLegendWindow(self.colors) legend_window.run() legend_window.destroy() self.refresh_diff(None) def refresh_diff (self, widget): """This method is called whenever the diff output might have changed, such as when a different scan was selected in one of the choosers.""" if self.compare_mode.get_active(): # Graphical comparison mode. parsed1 = self.scan_chooser1.parsed_scan parsed2 = self.scan_chooser2.parsed_scan if parsed1 is not None and parsed2 is not None: self.compare_view.make_diff(parsed1, parsed2) else: self.compare_view.clear_diff_tree() self.compare_view.activate_color(self.check_color.get_active()) else: # Text comparison mode. text1 = self.scan_chooser1.nmap_output text2 = self.scan_chooser2.nmap_output if text1 is not None and text2 is not None: diff = Diff(text1.split('\n'), text2.split('\n')) self.text_view.set_text('\n'.join(diff.generate_without_banner())) else: self.text_view.clear() self.text_view.activate_color(self.check_color.get_active()) def resize_vpane(self, widget): exp1 = not widget.get_expanded() if widget == self.scan_chooser1.exp_scan: exp2 = self.scan_chooser2.exp_scan.get_expanded() else: exp2 = self.scan_chooser1.exp_scan.get_expanded() if not exp1 and not exp2: self.vpaned.compute_position(-1, 0, 500) self.size_allocate(gtk.gdk.Rectangle(width=self.initial_size[0], height=self.initial_size[1])) self.queue_resize() def _change_to_text(self, widget): if not widget.get_active(): return self.umit_conf.diff_mode = "text" children = self.hbox_result.get_children() if children: self.hbox_result.remove(children[0]) self.compare_view.hide() self.hbox_result._pack_expand_fill(self.text_view) self.text_view.show_all() self.compare_mode.set_active(False) self.refresh_diff(None) def _change_to_compare(self, widget): if not widget.get_active(): return self.umit_conf.diff_mode = "compare" children = self.hbox_result.get_children() if children: self.hbox_result.remove(children[0]) self.text_view.hide() self.hbox_result._pack_expand_fill(self.compare_view) self.compare_view.show_all() self.text_mode.set_active(False) self.refresh_diff(None) def _set_color(self, widget): activate = widget.get_active() self.umit_conf.colored_diff = activate self.compare_view.activate_color(activate) self.text_view.activate_color(activate) def close(self, widget=None, extra=None): if self.temp_html_file is not None: self.temp_html_file.close() self.destroy()