1
0
mirror of https://github.com/nmap/nmap.git synced 2026-01-11 08:59:04 +00:00

Apply PEP 8 style guidance to zenmap

Using the pep8 tool (https://pypi.python.org/pypi/pep8), fixed the
following style issues:

Count   Issue
11      E201 whitespace after '['
8       E203 whitespace before ','
41      E211 whitespace before '('
11      E221 multiple spaces before operator
61      E225 missing whitespace around operator
237     E231 missing whitespace after ':'
91      E251 no spaces around keyword / parameter equals
19      E261 at least two spaces before inline comment
41      E301 expected 1 blank line, found 0
200     E302 expected 2 blank lines, found 1
356     E303 too many blank lines (2)
563     E501 line too long (106 characters)
39      E701 multiple statements on one line (colon)
13      E702 multiple statements on one line (semicolon)
4       W291 trailing whitespace
2       W293 blank line contains whitespace
8       W391 blank line at end of file
21      W601 .has_key() is deprecated, use 'in'
2       W602 deprecated form of raising exception

The remaining issues are long lines due to very deep data structures. I
chose not to alter them, as it would involve backslash-continuation
where whitespace is not permitted:

./zenmapGUI/ScanInterface.py:323:80: E501 line too long (90 characters)
./zenmapGUI/ScanInterface.py:456:80: E501 line too long (84 characters)
./zenmapGUI/ScanInterface.py:464:80: E501 line too long (84 characters)
./zenmapGUI/ScanInterface.py:472:80: E501 line too long (122 characters)
./zenmapGUI/ScanInterface.py:479:80: E501 line too long (122 characters)
./zenmapGUI/ScanInterface.py:920:80: E501 line too long (94 characters)
./zenmapGUI/ScanInterface.py:923:80: E501 line too long (93 characters)
./zenmapGUI/MainWindow.py:575:80: E501 line too long (99 characters)
./zenmapGUI/MainWindow.py:906:80: E501 line too long (99 characters)
This commit is contained in:
dmiller
2014-01-08 19:50:22 +00:00
parent 9210a7f1fa
commit 5c662fffdc
100 changed files with 2287 additions and 1814 deletions

View File

@@ -126,7 +126,8 @@ import webbrowser
from zenmapGUI.higwidgets.higdialogs import HIGDialog
from zenmapGUI.higwidgets.higwindows import HIGWindow
from zenmapGUI.higwidgets.higboxes import HIGVBox, HIGHBox, hig_box_space_holder
from zenmapGUI.higwidgets.higboxes import HIGVBox, HIGHBox, \
hig_box_space_holder
from zenmapGUI.higwidgets.higbuttons import HIGButton
from zenmapGUI.higwidgets.hignotebooks import HIGNotebook
from zenmapGUI.higwidgets.higscrollers import HIGScrolledWindow
@@ -141,6 +142,7 @@ import zenmapCore.I18N
# For escaping text in marked-up labels.
from xml.sax.saxutils import escape
class _program_entry(gtk.VBox):
"""A little box containing labels with a program's name and
description and a clickable link to its web site."""
@@ -149,7 +151,7 @@ class _program_entry(gtk.VBox):
# web site button.
NAME_WEB_SITE_SPACING = 20
def __init__(self, name = None, web_site = None, description = None):
def __init__(self, name=None, web_site=None, description=None):
gtk.VBox.__init__(self)
self.hbox = gtk.HBox(False, self.NAME_WEB_SITE_SPACING)
@@ -157,7 +159,9 @@ class _program_entry(gtk.VBox):
if name is not None:
name_label = gtk.Label()
name_label.set_markup("<span size=\"large\" weight=\"bold\">%s</span>" % escape(name))
name_label.set_markup(
'<span size="large" weight="bold">%s</span>' % escape(
name))
self.hbox.pack_start(name_label, False)
if web_site is not None:
@@ -180,41 +184,44 @@ class _program_entry(gtk.VBox):
def _link_button_open(self, widget):
webbrowser.open(widget.get_uri())
class About(HIGDialog):
"""An about dialog showing information about the program. It is meant to
have roughly the same feel as gtk.AboutDialog."""
def __init__(self):
HIGDialog.__init__(self)
self.set_title(_("About %s and %s") % (NMAP_DISPLAY_NAME, APP_DISPLAY_NAME))
self.set_title(_("About %s and %s") % (
NMAP_DISPLAY_NAME, APP_DISPLAY_NAME))
self.vbox.set_border_width(12)
self.vbox.set_spacing(12)
label = gtk.Label()
label.set_markup("<span size=\"xx-large\" weight=\"bold\">%s %s</span>" \
% (escape(APP_DISPLAY_NAME), escape(VERSION)))
label.set_markup(
'<span size="xx-large" weight="bold">%s %s</span>' % (
escape(APP_DISPLAY_NAME), escape(VERSION)))
label.set_selectable(True)
self.vbox.pack_start(label)
label = gtk.Label()
label.set_markup("<span size=\"small\">%s</span>" \
% (escape(APP_COPYRIGHT)))
label.set_markup(
'<span size="small">%s</span>' % (escape(APP_COPYRIGHT)))
self.vbox.pack_start(label)
entry = _program_entry(NMAP_DISPLAY_NAME, NMAP_WEB_SITE, _("""\
%s is a free and open source utility for network exploration and security \
auditing.""") % NMAP_DISPLAY_NAME)
entry = _program_entry(NMAP_DISPLAY_NAME, NMAP_WEB_SITE, _(
"%s is a free and open source utility for network exploration "
"and security auditing.") % NMAP_DISPLAY_NAME)
self.vbox.pack_start(entry)
entry = _program_entry(APP_DISPLAY_NAME, APP_WEB_SITE, _("""\
%s is a multi-platform graphical %s frontend and results viewer. It was \
originally derived from %s.""") \
% (APP_DISPLAY_NAME, NMAP_DISPLAY_NAME, UMIT_DISPLAY_NAME))
entry = _program_entry(APP_DISPLAY_NAME, APP_WEB_SITE, _(
"%s is a multi-platform graphical %s frontend and results viewer. "
"It was originally derived from %s.") % (
APP_DISPLAY_NAME, NMAP_DISPLAY_NAME, UMIT_DISPLAY_NAME))
self.vbox.pack_start(entry)
entry = _program_entry(UMIT_DISPLAY_NAME, UMIT_WEB_SITE, _("""\
%s is an %s GUI created as part of the Nmap/Google Summer of Code program.""") \
% (UMIT_DISPLAY_NAME, NMAP_DISPLAY_NAME))
entry = _program_entry(UMIT_DISPLAY_NAME, UMIT_WEB_SITE, _(
"%s is an %s GUI created as part of the Nmap/Google Summer "
"of Code program.") % (UMIT_DISPLAY_NAME, NMAP_DISPLAY_NAME))
button = gtk.Button(_("%s credits") % UMIT_DISPLAY_NAME)
button.connect("clicked", self._show_umit_credits)
entry.hbox.pack_start(button, False)
@@ -246,17 +253,20 @@ originally derived from %s.""") \
return
self._umit_credits_dialog = UmitCredits()
def credits_destroyed(widget):
# Mark that the credits dialog has been destroyed.
self._umit_credits_dialog = None
self._umit_credits_dialog.connect("destroy", credits_destroyed)
self._umit_credits_dialog.show_all()
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_size_request(-1, 250)
self.set_position(gtk.WIN_POS_CENTER)
self.__create_widgets()
@@ -296,12 +306,18 @@ class UmitCredits(HIGWindow):
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.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)
@@ -321,7 +337,7 @@ class UmitCredits(HIGWindow):
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())
self.btn_close.connect('clicked', lambda x, y=None: self.destroy())
def set_text(self):
b = self.written_by_text.get_buffer()

View File

@@ -133,7 +133,7 @@ import ConfigParser
# Python 2.7 that otherwise causes an assertion failure. See
# https://bugzilla.redhat.com/show_bug.cgi?id=620216#c10.
import warnings
warnings.filterwarnings("error", module = "gtk", append = "True")
warnings.filterwarnings("error", module="gtk", append="True")
try:
import gtk
except Exception:
@@ -171,6 +171,7 @@ from zenmapGUI.higwidgets.higdialogs import HIGAlertDialog
# gtk.main_quit.
open_windows = []
def _destroy_callback(window):
open_windows.remove(window)
if len(open_windows) == 0:
@@ -183,6 +184,7 @@ def _destroy_callback(window):
# Cleaning up data base
UmitDB().cleanup(SearchConfig().converted_save_time)
def new_window():
w = ScanWindow()
w.connect("destroy", _destroy_callback)
@@ -193,11 +195,14 @@ def new_window():
open_windows.append(w)
return w
# Script found at http://www.py2exe.org/index.cgi/HowToDetermineIfRunningFromExe
# Script found at
# http://www.py2exe.org/index.cgi/HowToDetermineIfRunningFromExe
def main_is_frozen():
return (hasattr(sys, "frozen") # new py2exe
or hasattr(sys, "importers") # old py2exe
or imp.is_frozen("__main__")) # tools/freeze
return (hasattr(sys, "frozen") # new py2exe
or hasattr(sys, "importers") # old py2exe
or imp.is_frozen("__main__")) # tools/freeze
def is_root():
if 'NMAP_PRIVILEGED' in os.environ:
@@ -207,6 +212,7 @@ def is_root():
else:
return sys.platform == "win32" or os.getuid() == 0 or is_maemo()
def install_excepthook():
# This will catch exceptions and send them to bugzilla
def excepthook(type, value, tb):
@@ -218,7 +224,7 @@ def install_excepthook():
# produces a warning, but the lack of a display eventually causes a
# segmentation fault. See http://live.gnome.org/PyGTK/WhatsNew210.
import warnings
warnings.filterwarnings("error", module = "gtk")
warnings.filterwarnings("error", module="gtk")
import gtk
warnings.resetwarnings()
@@ -229,8 +235,7 @@ def install_excepthook():
if type == ImportError:
d = HIGAlertDialog(type=gtk.MESSAGE_ERROR,
message_format=_("Import error"),
secondary_text=_("""\
A required module was not found.
secondary_text=_("""A required module was not found.
""" + unicode(value)))
d.run()
@@ -246,6 +251,7 @@ A required module was not found.
sys.excepthook = excepthook
def safe_shutdown(signum, stack):
"""Kills any active scans/tabs and shuts down the application."""
log.debug("\n\n%s\nSAFE SHUTDOWN!\n%s\n" % ("#" * 30, "#" * 30))
@@ -256,6 +262,7 @@ def safe_shutdown(signum, stack):
sys.exit(signum)
def run():
if os.name == "posix":
signal.signal(signal.SIGHUP, safe_shutdown)
@@ -271,19 +278,25 @@ def run():
try:
# Create the ~/.zenmap directory by copying from the system-wide
# template directory.
zenmapCore.Paths.create_user_config_dir(Path.user_config_dir, Path.config_dir)
zenmapCore.Paths.create_user_config_dir(
Path.user_config_dir, Path.config_dir)
except (IOError, OSError), e:
error_dialog = HIGAlertDialog(message_format = _("Error creating the per-user configuration directory"),
secondary_text = _("""\
error_dialog = HIGAlertDialog(
message_format=_(
"Error creating the per-user configuration directory"),
secondary_text=_("""\
There was an error creating the directory %s or one of the files in it. \
The directory is created by copying the contents of %s. \
The specific error was\n\
\n\
%s\n\
\n\
The specific error was
%s
%s needs to create this directory to store information such as the list of \
scan profiles. Check for access to the directory and try again.\
""") % (repr(Path.user_config_dir), repr(Path.config_dir), repr(str(e)), APP_DISPLAY_NAME))
scan profiles. Check for access to the directory and try again.""") % (
repr(Path.user_config_dir), repr(Path.config_dir),
repr(str(e)), APP_DISPLAY_NAME
)
)
error_dialog.run()
error_dialog.destroy()
sys.exit(1)
@@ -292,16 +305,17 @@ scan profiles. Check for access to the directory and try again.\
# Read the ~/.zenmap/zenmap.conf configuration file.
zenmapCore.UmitConf.config_parser.read(Path.user_config_file)
except ConfigParser.ParsingError, e:
error_dialog = HIGAlertDialog(message_format = _("Error parsing the configuration file"),
secondary_text = _("""\
error_dialog = HIGAlertDialog(
message_format=_("Error parsing the configuration file"),
secondary_text=_("""\
There was an error parsing the configuration file %s. \
The specific error was\n\
\n\
%s\n\
\n\
The specific error was
%s
%s can continue without this file but any information in it will be ignored \
until it is repaired.\
""") % (Path.user_config_file, str(e), APP_DISPLAY_NAME))
until it is repaired.""") % (Path.user_config_file, str(e), APP_DISPLAY_NAME)
)
error_dialog.run()
error_dialog.destroy()
@@ -355,10 +369,13 @@ until it is repaired.\
if main_is_frozen():
gtk.gdk.threads_leave()
class NonRootWarning (HIGAlertDialog):
def __init__(self):
warning_text = _('''You are trying to run %s with a non-root user!\n
Some %s options need root privileges to work.''') % (APP_DISPLAY_NAME, NMAP_DISPLAY_NAME)
warning_text = _('''You are trying to run %s with a non-root user!
Some %s options need root privileges to work.''') % (
APP_DISPLAY_NAME, NMAP_DISPLAY_NAME)
HIGAlertDialog.__init__(self, message_format=_('Non-root user'),
secondary_text=warning_text)

View File

@@ -130,6 +130,7 @@ import zenmapCore.I18N
# For escaping text in marked-up labels.
from xml.sax.saxutils import escape
class BugReport(gtk.Window, object):
def __init__(self):
gtk.Window.__init__(self)
@@ -173,7 +174,11 @@ Code patches to fix bugs are even better than bug reports. Basic \
instructions for creating patch files with your changes are available at \
http://nmap.org/data/HACKING. Patches may be sent to nmap-dev \
(recommended) or to Fyodor directly.
""") % {"app": escape(APP_DISPLAY_NAME), "nmap": escape(NMAP_DISPLAY_NAME), "nmap_web": escape(NMAP_WEB_SITE)})
""") % {
"app": escape(APP_DISPLAY_NAME),
"nmap": escape(NMAP_DISPLAY_NAME),
"nmap_web": escape(NMAP_WEB_SITE)
})
self.vbox.add(self.text)
self.button_box.set_layout(gtk.BUTTONBOX_END)

View File

@@ -134,6 +134,7 @@ import zenmapCore.I18N
# For escaping text in marked-up labels.
from xml.sax.saxutils import escape
class CrashReport(HIGDialog):
def __init__(self, type, value, tb):
HIGDialog.__init__(self)
@@ -158,17 +159,16 @@ class CrashReport(HIGDialog):
self.description_text.set_editable(False)
self.bug_text = gtk.Label()
self.bug_text.set_markup(_("""\
An unexpected error has crashed %(app_name)s. Please copy the stack trace below and \
send it to the <a href="mailto:dev@nmap.org">dev@nmap.org</a> \
mailing list. (<a href="http://seclists.org/nmap-dev/">More about the list.</a>) \
The developers will see your report and try to fix the problem.""") % \
{ "app_name": escape(APP_DISPLAY_NAME) })
self.bug_text.set_markup(_('An unexpected error has crashed '
'%(app_name)s. Please copy the stack trace below and send it to '
'the <a href="mailto:dev@nmap.org">dev@nmap.org</a> mailing list. '
'(<a href="http://seclists.org/nmap-dev/">More about the list.</a>'
') The developers will see your report and try to fix the problem.'
) % {"app_name": escape(APP_DISPLAY_NAME)})
self.email_frame = gtk.Frame()
self.email_label = gtk.Label()
self.email_label.set_markup(_("""\
<b>Copy and email to <a href="mailto:dev@nmap.org">dev@nmap.org</a>:</b>\
"""))
self.email_label.set_markup(_('<b>Copy and email to '
'<a href="mailto:dev@nmap.org">dev@nmap.org</a>:</b>'))
self.btn_copy = gtk.Button(stock=gtk.STOCK_COPY)
self.btn_ok = gtk.Button(stock=gtk.STOCK_OK)
@@ -176,7 +176,8 @@ The developers will see your report and try to fix the problem.""") % \
def _pack_widgets(self):
self.description_scrolled.add(self.description_text)
self.description_scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self.description_scrolled.set_policy(
gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self.description_scrolled.set_size_request(400, 150)
self.description_text.set_wrap_mode(gtk.WRAP_WORD)
@@ -223,7 +224,7 @@ The developers will see your report and try to fix the problem.""") % \
sys.exit(0)
if __name__ == "__main__":
c = CrashReport(None,None,None)
c = CrashReport(None, None, None)
c.show_all()
c.connect("delete-event", lambda x, y: gtk.main_quit())

View File

@@ -129,7 +129,8 @@ import sys
import xml.sax
from zenmapGUI.higwidgets.higdialogs import HIGAlertDialog, HIGDialog
from zenmapGUI.higwidgets.higboxes import HIGVBox, HIGHBox, hig_box_space_holder
from zenmapGUI.higwidgets.higboxes import HIGVBox, HIGHBox, \
hig_box_space_holder
from zenmapGUI.higwidgets.higlabels import HIGSectionLabel
from zenmapGUI.higwidgets.higtables import HIGTable
from zenmapGUI.higwidgets.higbuttons import HIGButton
@@ -144,6 +145,7 @@ from zenmapGUI.FileChoosers import ResultsFileSingleChooserDialog
# In milliseconds.
NDIFF_CHECK_TIMEOUT = 200
class ScanChooser(HIGVBox):
"""This class allows the selection of scan results from the list of open
tabs or from a file. It emits the "changed" signal when the scan selection
@@ -193,7 +195,7 @@ class ScanChooser(HIGVBox):
def get_buffer(self):
return self.txt_scan_result.get_buffer()
def show_scan (self, widget):
def show_scan(self, widget):
nmap_output = self.get_nmap_output()
if nmap_output is not None:
self.txt_scan_result.get_buffer().set_text(nmap_output)
@@ -201,14 +203,15 @@ class ScanChooser(HIGVBox):
def normalize_output(self, output):
return "\n".join(output.split("\\n"))
def _pack_hbox (self):
def _pack_hbox(self):
self.hbox._pack_noexpand_nofill(hig_box_space_holder())
self.hbox._pack_expand_fill(self.table)
def _attaching_widgets (self):
self.table.attach(self.combo_scan, 0,1,0,1, yoptions=0)
self.table.attach(self.btn_open_scan, 1,2,0,1, yoptions=0, xoptions=0)
self.table.attach(self.exp_scan, 0,2,1,2)
def _attaching_widgets(self):
self.table.attach(self.combo_scan, 0, 1, 0, 1, yoptions=0)
self.table.attach(
self.btn_open_scan, 1, 2, 0, 1, yoptions=0, xoptions=0)
self.table.attach(self.exp_scan, 0, 2, 1, 2)
def _set_scrolled(self):
self.scrolled.set_border_width(5)
@@ -223,19 +226,20 @@ class ScanChooser(HIGVBox):
# Setting scrolled window
self.scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
def _set_text_view (self):
def _set_text_view(self):
self.txg_table = self.txt_scan_result.get_buffer().get_tag_table()
self.txg_table.add(self.txg_tag)
self.txg_tag.set_property("family", "Monospace")
self.txt_scan_result.set_wrap_mode(gtk.WRAP_WORD)
self.txt_scan_result.set_editable(False)
self.txt_scan_result.get_buffer().connect("changed", self._text_changed_cb)
self.txt_scan_result.get_buffer().connect(
"changed", self._text_changed_cb)
def _set_open_button (self):
def _set_open_button(self):
self.btn_open_scan.connect('clicked', self.open_file)
def open_file (self, widget):
def open_file(self, widget):
file_chooser = ResultsFileSingleChooserDialog(_("Select Scan Result"))
response = file_chooser.run()
@@ -248,15 +252,19 @@ class ScanChooser(HIGVBox):
except xml.sax.SAXParseException, e:
alert = HIGAlertDialog(
message_format='<b>%s</b>' % _('Error parsing file'),
secondary_text=_("The file is not an Nmap XML output file. \
The parsing error that occurred was\n%s") % str(e))
secondary_text=_(
"The file is not an Nmap XML output file. "
"The parsing error that occurred was\n%s") % str(e))
alert.run()
alert.destroy()
return False
except Exception, e:
alert = HIGAlertDialog(
message_format='<b>%s</b>' % _('Cannot open selected file'),
secondary_text=_("This error occurred while trying to open the file:\n%s") % str(e))
message_format='<b>%s</b>' % _(
'Cannot open selected file'),
secondary_text=_("""\
This error occurred while trying to open the file:
%s""") % str(e))
alert.run()
alert.destroy()
return False
@@ -276,9 +284,10 @@ The parsing error that occurred was\n%s") % str(e))
self.list_scan.append([new_scan_name])
self.scan_dict[new_scan_name] = parser
def _text_changed_cb (self, widget):
buff = self.txt_scan_result.get_buffer ()
buff.apply_tag(self.txg_tag, buff.get_start_iter(), buff.get_end_iter())
def _text_changed_cb(self, widget):
buff = self.txt_scan_result.get_buffer()
buff.apply_tag(
self.txg_tag, buff.get_start_iter(), buff.get_end_iter())
def get_parsed_scan(self):
"""Return the currently selected scan's parsed output as an NmapParser
@@ -306,9 +315,10 @@ class DiffWindow(gtk.Window):
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.
# 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
@@ -358,12 +368,13 @@ class DiffWindow(gtk.Window):
self.scan_chooser_a.connect('changed', self.refresh_diff)
self.scan_chooser_b.connect('changed', self.refresh_diff)
def refresh_diff (self, widget):
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:
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
@@ -378,14 +389,17 @@ class DiffWindow(gtk.Window):
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"))
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)
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.
@@ -412,21 +426,23 @@ class DiffWindow(gtk.Window):
diff = self.ndiff_process.get_scan_diff()
except zenmapCore.Diff.NdiffParseException, e:
alert = HIGAlertDialog(
message_format = _("Error parsing ndiff output"),
secondary_text = str(e))
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
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)
message_format=_("Error running ndiff"),
secondary_text=error_text)
alert.run()
alert.destroy()
@@ -445,6 +461,7 @@ class DiffWindow(gtk.Window):
def close(self, widget=None, extra=None):
self.destroy()
class DiffView(gtk.TextView):
REMOVE_COLOR = "#ffaaaa"
ADD_COLOR = "#ccffcc"
@@ -456,9 +473,10 @@ class DiffView(gtk.TextView):
buff = self.get_buffer()
# Create text markup tags.
buff.create_tag("=", font = "Monospace")
buff.create_tag("-", font = "Monospace", background = self.REMOVE_COLOR)
buff.create_tag("+", font = "Monospace", background = self.ADD_COLOR)
buff.create_tag("=", font="Monospace")
buff.create_tag(
"-", font="Monospace", background=self.REMOVE_COLOR)
buff.create_tag("+", font="Monospace", background=self.ADD_COLOR)
def clear(self):
self.get_buffer().set_text(u"")
@@ -494,6 +512,6 @@ if __name__ == "__main__":
"Parsed 4": parsed4})
dw.show_all()
dw.connect("delete-event", lambda x,y: gtk.main_quit())
dw.connect("delete-event", lambda x, y: gtk.main_quit())
gtk.main()

View File

@@ -128,6 +128,7 @@ import zenmapCore.I18N
RESPONSE_OPEN_DIRECTORY = 1
class AllFilesFileFilter(gtk.FileFilter):
def __init__(self):
gtk.FileFilter.__init__(self)
@@ -136,6 +137,7 @@ class AllFilesFileFilter(gtk.FileFilter):
self.add_pattern(pattern)
self.set_name(_("All files (%s)") % pattern)
class ResultsFileFilter(gtk.FileFilter):
def __init__(self):
gtk.FileFilter.__init__(self)
@@ -145,6 +147,7 @@ class ResultsFileFilter(gtk.FileFilter):
self.add_pattern(pattern)
self.set_name(_("Nmap XML files (%s)") % ", ".join(patterns))
class ScriptFileFilter(gtk.FileFilter):
def __init__(self):
gtk.FileFilter.__init__(self)
@@ -154,6 +157,7 @@ class ScriptFileFilter(gtk.FileFilter):
self.add_pattern(pattern)
self.set_name(_("NSE scripts (%s)") % ", ".join(patterns))
class UnicodeFileChooserDialog(gtk.FileChooserDialog):
"""This is a base class for file choosers. It is designed to ease the
retrieval of Unicode file names. On most platforms, the file names returned
@@ -173,6 +177,7 @@ class UnicodeFileChooserDialog(gtk.FileChooserDialog):
pass
return filename
class AllFilesFileChooserDialog(UnicodeFileChooserDialog):
def __init__(self, title="", parent=None,
action=gtk.FILE_CHOOSER_ACTION_OPEN,
@@ -184,6 +189,7 @@ class AllFilesFileChooserDialog(UnicodeFileChooserDialog):
self.set_default_response(gtk.RESPONSE_OK)
self.add_filter(AllFilesFileFilter())
class ResultsFileSingleChooserDialog(UnicodeFileChooserDialog):
"""This results file choose only allows the selection of single files, not
directories."""
@@ -198,6 +204,7 @@ class ResultsFileSingleChooserDialog(UnicodeFileChooserDialog):
for f in (ResultsFileFilter(), AllFilesFileFilter()):
self.add_filter(f)
class ResultsFileChooserDialog(UnicodeFileChooserDialog):
def __init__(self, title="", parent=None,
action=gtk.FILE_CHOOSER_ACTION_OPEN,
@@ -211,6 +218,7 @@ class ResultsFileChooserDialog(UnicodeFileChooserDialog):
for f in (ResultsFileFilter(), AllFilesFileFilter()):
self.add_filter(f)
class ScriptFileChooserDialog(UnicodeFileChooserDialog):
def __init__(self, title="", parent=None,
action=gtk.FILE_CHOOSER_ACTION_OPEN,
@@ -224,6 +232,7 @@ class ScriptFileChooserDialog(UnicodeFileChooserDialog):
for f in (ScriptFileFilter(), AllFilesFileFilter()):
self.add_filter(f)
class SaveResultsFileChooserDialog(UnicodeFileChooserDialog):
TYPES = (
(_("By extension"), None, None),
@@ -286,12 +295,14 @@ class SaveResultsFileChooserDialog(UnicodeFileChooserDialog):
def get_format(self):
"""Get the save format the user has chosen. It is a string, either
"text" or "xml"."""
filetype = self.combo.get_model().get_value(self.combo.get_active_iter(), 1)
filetype = self.combo.get_model().get_value(
self.combo.get_active_iter(), 1)
if filetype is None:
# Guess based on extension. "xml" is the default if unknown.
return self.EXTENSIONS.get(self.get_extension(), "xml")
return filetype
class DirectoryChooserDialog(UnicodeFileChooserDialog):
def __init__(self, title="", parent=None,
action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
@@ -301,6 +312,7 @@ class DirectoryChooserDialog(UnicodeFileChooserDialog):
UnicodeFileChooserDialog.__init__(self, title, parent, action, buttons)
self.set_default_response(gtk.RESPONSE_OK)
class SaveToDirectoryChooserDialog(UnicodeFileChooserDialog):
def __init__(self, title="", parent=None,
action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,

View File

@@ -4,6 +4,7 @@ import gobject
from zenmapGUI.higwidgets.higboxes import HIGHBox
from zenmapGUI.higwidgets.higlabels import HintWindow
class FilterBar(HIGHBox):
"""This is the bar that appears while the host filter is active. It allows
entering a string that restricts the set of visible hosts."""

View File

@@ -171,13 +171,18 @@ if pixmap_path:
# Try again.
pass
else:
log.warn('Could not find the icon for %s at any of (%s) in %s' % (icon_name, ', '.join(get_pixmap_file_names(icon_name, size)), pixmap_path))
log.warn('Could not find the icon for %s at '
'any of (%s) in %s' % (
icon_name,
', '.join(get_pixmap_file_names(icon_name, size)),
pixmap_path))
continue
iconset = gtk.IconSet(pixbuf)
iconfactory.add(key, iconset)
log.debug('Register %s icon name for file %s' % (key, file_path))
iconfactory.add_default()
def get_os_icon(host):
osmatch = host.get_best_osmatch()
if osmatch and osmatch['osclasses']:
@@ -190,6 +195,7 @@ def get_os_icon(host):
else:
return get_os(None, None, 'icon')
def get_os_logo(host):
osmatch = host.get_best_osmatch()
if osmatch and osmatch['osclasses']:
@@ -202,51 +208,53 @@ def get_os_logo(host):
else:
return get_os(None, None, 'logo')
def get_os(osfamily, osmatch, type):
if osfamily:
if osfamily == 'Linux':
if re.findall("ubuntu", osmatch.lower()):
# Ubuntu icon
return 'ubuntu_%s'%type
return 'ubuntu_%s' % type
elif re.findall("red hat", osmatch.lower()):
# RedHat icon
return 'redhat_%s'%type
return 'redhat_%s' % type
else:
# Generic Linux icon
return 'linux_%s'%type
return 'linux_%s' % type
elif osfamily == 'Windows':
# Windows icon
return 'win_%s'%type
return 'win_%s' % type
elif osfamily == 'OpenBSD':
# OpenBSD icon
return 'openbsd_%s'%type
return 'openbsd_%s' % type
elif osfamily == 'FreeBSD':
# FreeBSD icon
return 'freebsd_%s'%type
return 'freebsd_%s' % type
elif osfamily == 'NetBSD':
# NetBSD icon
return 'default_%s'%type
return 'default_%s' % type
elif osfamily == 'Solaris':
# Solaris icon
return 'solaris_%s'%type
return 'solaris_%s' % type
elif osfamily == 'OpenSolaris':
# OpenSolaris icon
return 'solaris_%s'%type
return 'solaris_%s' % type
elif osfamily == 'IRIX':
# Irix icon
return 'irix_%s'%type
return 'irix_%s' % type
elif osfamily == 'Mac OS X':
# Mac OS X icon
return 'macosx_%s'%type
return 'macosx_%s' % type
elif osfamily == 'Mac OS':
# Mac OS icon
return 'macosx_%s'%type
return 'macosx_%s' % type
else:
# Default OS icon
return 'default_%s'%type
return 'default_%s' % type
else:
# Unknown OS icon
return 'unknown_%s'%type
return 'unknown_%s' % type
def get_vulnerability_logo(open_ports):
open_ports = int(open_ports)

View File

@@ -159,6 +159,7 @@ hildon = None
if is_maemo():
import hildon
class UmitScanWindow(hildon.Window):
def __init__(self):
hildon.Window.__init__(self)
@@ -174,9 +175,10 @@ else:
HIGMainWindow.__init__(self)
self.vbox = gtk.VBox()
def can_print():
"""Return true if we have printing operations (PyGTK 2.10 or later) or false
otherwise."""
"""Return true if we have printing operations (PyGTK 2.10 or later) or
false otherwise."""
try:
gtk.PrintOperation
except AttributeError:
@@ -184,6 +186,7 @@ def can_print():
else:
return True
class ScanWindow(UmitScanWindow):
def __init__(self):
UmitScanWindow.__init__(self)
@@ -199,7 +202,7 @@ class ScanWindow(UmitScanWindow):
# self.vbox is a container for the menubar and the scan interface
self.add(self.vbox)
self.connect ('delete-event', self._exit_cb)
self.connect('delete-event', self._exit_cb)
self._create_ui_manager()
self._create_menubar()
self._create_scan_interface()
@@ -433,25 +436,29 @@ class ScanWindow(UmitScanWindow):
def _search_scan_result(self, widget):
"""Displays a search window."""
search_window = SearchWindow(self._load_search_result, self._append_search_result)
search_window = SearchWindow(
self._load_search_result, self._append_search_result)
search_window.show_all()
def _filter_cb(self, widget):
self.scan_interface.toggle_filter_bar()
def _load_search_result(self, results):
"""This function is passed as an argument to the SearchWindow.__init__ method.
When the user selects scans in the search window and clicks on \"Open\", this
function is called to load each of the selected scans into a new window."""
"""This function is passed as an argument to the SearchWindow.__init__
method. When the user selects scans in the search window and clicks on
"Open", this function is called to load each of the selected scans into
a new window."""
for result in results:
self._load(self.get_empty_interface(), parsed_result = results[result][1])
self._load(self.get_empty_interface(),
parsed_result=results[result][1])
def _append_search_result(self, results):
"""This function is passed as an argument to the SearchWindow.__init__ method.
When the user selects scans in the search window and clicks on \"Append\", this
function is called to append the selected scans into the current window."""
"""This function is passed as an argument to the SearchWindow.__init__
method. When the user selects scans in the search window and clicks on
"Append", this function is called to append the selected scans into the
current window."""
for result in results:
self._load(self.scan_interface, parsed_result = results[result][1])
self._load(self.scan_interface, parsed_result=results[result][1])
def store_result(self, scan_interface):
"""Stores the network inventory into the database."""
@@ -459,23 +466,28 @@ class ScanWindow(UmitScanWindow):
try:
scan_interface.inventory.save_to_db()
except Exception, e:
alert = HIGAlertDialog(message_format = _("Can't save to database"),
secondary_text = _("Can't store unsaved scans to the recent scans database:\n%s") % str(e))
alert = HIGAlertDialog(
message_format=_("Can't save to database"),
secondary_text=_("Can't store unsaved scans to the "
"recent scans database:\n%s") % str(e))
alert.run()
alert.destroy()
log.debug(">>> Can't save result to database: %s." % str(e))
def get_recent_scans(self):
"""Gets seven most recent scans and appends them to the default UI definition."""
"""Gets seven most recent scans and appends them to the default UI
definition."""
r_scans = recent_scans.get_recent_scans_list()
new_rscan_xml = ''
for scan in r_scans[:7]:
scan = scan.replace('\n','')
if os.access(split(scan)[0],os.R_OK) and isfile(scan):
scan = scan.replace('\n','')
new_rscan = (scan, None, scan, None, scan, self._load_recent_scan)
new_rscan_xml += "<menuitem action=%s/>\n" % xml.sax.saxutils.quoteattr(scan)
scan = scan.replace('\n', '')
if os.access(split(scan)[0], os.R_OK) and isfile(scan):
scan = scan.replace('\n', '')
new_rscan = (
scan, None, scan, None, scan, self._load_recent_scan)
new_rscan_xml += "<menuitem action=%s/>\n" % (
xml.sax.saxutils.quoteattr(scan))
self.main_actions.append(new_rscan)
else:
@@ -501,16 +513,19 @@ class ScanWindow(UmitScanWindow):
self.menubar.show_all()
def _create_scan_interface(self):
self.scan_interface.scan_result.scan_result_notebook.scans_list.append_button.connect("clicked", self._append_scan_results_cb)
self.scan_interface.scan_result.scan_result_notebook.nmap_output.connect("changed", self._displayed_scan_change_cb)
notebook = self.scan_interface.scan_result.scan_result_notebook
notebook.scans_list.append_button.connect(
"clicked", self._append_scan_results_cb)
notebook.nmap_output.connect("changed", self._displayed_scan_change_cb)
self._displayed_scan_change_cb(None)
self.scan_interface.show_all()
self.vbox.pack_start(self.scan_interface, True, True, 0)
def show_open_dialog(self, title = None):
def show_open_dialog(self, title=None):
"""Show a load file chooser and return the filename chosen."""
if self._results_filechooser_dialog is None:
self._results_filechooser_dialog = ResultsFileChooserDialog(title = title)
self._results_filechooser_dialog = ResultsFileChooserDialog(
title=title)
filename = None
response = self._results_filechooser_dialog.run()
@@ -519,8 +534,9 @@ class ScanWindow(UmitScanWindow):
elif response == RESPONSE_OPEN_DIRECTORY:
filename = self._results_filechooser_dialog.get_filename()
# Check if the selected filename is a directory. If not, we take only the
# directory part of the path, omitting the actual name of the selected file.
# Check if the selected filename is a directory. If not, we take
# only the directory part of the path, omitting the actual name of
# the selected file.
if filename is not None and not os.path.isdir(filename):
filename = os.path.dirname(filename)
@@ -528,8 +544,9 @@ class ScanWindow(UmitScanWindow):
return filename
def _load_scan_results_cb(self, p):
"""'Open Scan' callback function. Displays a file chooser dialog and loads the
scan from the selected file or from the selected directory."""
"""'Open Scan' callback function. Displays a file chooser dialog and
loads the scan from the selected file or from the selected
directory."""
filename = self.show_open_dialog(p.get_name())
if filename is not None:
scan_interface = self.get_empty_interface()
@@ -539,8 +556,8 @@ class ScanWindow(UmitScanWindow):
self._load(scan_interface, filename)
def _append_scan_results_cb(self, p):
"""'Append Scan' callback function. Displays a file chooser dialog and appends the
scan from the selected file into the current window."""
"""'Append Scan' callback function. Displays a file chooser dialog and
appends the scan from the selected file into the current window."""
filename = self.show_open_dialog(p.get_name())
if filename is not None:
if os.path.isdir(filename):
@@ -559,7 +576,8 @@ class ScanWindow(UmitScanWindow):
widget.set_sensitive(entry is not None)
def _load_recent_scan(self, widget):
"""A helper function for loading a recent scan directly from the menu."""
"""A helper function for loading a recent scan directly from the
menu."""
self._load(self.get_empty_interface(), widget.get_name())
def _load(self, scan_interface, filename=None, parsed_result=None):
@@ -587,54 +605,59 @@ class ScanWindow(UmitScanWindow):
def _load_directory(self, scan_interface, directory):
for file in os.listdir(directory):
if os.path.isdir(os.path.join(directory,file)):
if os.path.isdir(os.path.join(directory, file)):
continue
self._load(scan_interface, filename = os.path.join(directory, file))
self._load(scan_interface, filename=os.path.join(directory, file))
def _save_scan_results_cb(self, widget):
"""'Save Scan' callback function. If it's OK to save the scan, it displays a
'Save File' dialog and saves the scan. If not, it displays an appropriate
alert dialog."""
"""'Save Scan' callback function. If it's OK to save the scan, it
displays a 'Save File' dialog and saves the scan. If not, it displays
an appropriate alert dialog."""
num_scans = len(self.scan_interface.inventory.get_scans())
if num_scans == 0:
alert = HIGAlertDialog(message_format=_('Nothing to save'),
secondary_text=_("""\
There are no scans with results to be saved. Run a scan with the "Scan" button \
first."""))
alert = HIGAlertDialog(
message_format=_('Nothing to save'),
secondary_text=_(
'There are no scans with results to be saved. '
'Run a scan with the "Scan" button first.'))
alert.run()
alert.destroy()
return
num_scans_running = self.scan_interface.num_scans_running()
if num_scans_running > 0:
if num_scans_running == 1:
text = _("There is a scan still running. Wait until it finishes and then save.")
text = _("There is a scan still running. "
"Wait until it finishes and then save.")
else:
text = _("There are %u scans still running. Wait until they finish and then save.")\
% num_scans_running
text = _("There are %u scans still running. Wait until they "
"finish and then save.") % num_scans_running
alert = HIGAlertDialog(message_format=_('Scan is running'),
secondary_text=text)
alert.run()
alert.destroy()
return
# If there's more than one scan in the inventory, display a warning dialog saying
# that only the most recent scan will be saved
# If there's more than one scan in the inventory, display a warning
# dialog saying that only the most recent scan will be saved
selected = 0
if num_scans > 1:
#text = _("You have %u scans loaded in the current view. Only the most recent scan " \
# "will be saved." % num_scans)
#alert = HIGAlertDialog(message_format=_("More than one scan loaded"),
# secondary_text=text)
#text = _("You have %u scans loaded in the current view. "
# "Only the most recent scan will be saved." % num_scans)
#alert = HIGAlertDialog(
# message_format=_("More than one scan loaded"),
# secondary_text=text)
#alert.run()
#alert.destroy()
dlg = HIGDialog(title="Choose a scan to save",
parent=self,
flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
gtk.STOCK_SAVE, gtk.RESPONSE_OK))
dlg.vbox.pack_start(gtk.Label("You have %u scans loaded in the current view.\n" \
"Select the scan which you would like to save." \
% num_scans), False)
dlg = HIGDialog(
title="Choose a scan to save",
parent=self,
flags=gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
gtk.STOCK_SAVE, gtk.RESPONSE_OK))
dlg.vbox.pack_start(gtk.Label(
"You have %u scans loaded in the current view.\n"
"Select the scan which you would like to save." % num_scans),
False)
scan_combo = gtk.combo_box_new_text()
for scan in self.scan_interface.inventory.get_scans():
scan_combo.append_text(scan.nmap_command)
@@ -653,7 +676,8 @@ first."""))
SaveResultsFileChooserDialog(title=_('Save Scan'))
# Supply a default file name if this scan was previously saved.
if self.scan_interface.saved_filename:
self._save_results_filechooser_dialog.set_filename(self.scan_interface.saved_filename)
self._save_results_filechooser_dialog.set_filename(
self.scan_interface.saved_filename)
response = self._save_results_filechooser_dialog.run()
@@ -680,19 +704,21 @@ This scan has not been run yet. Start the scan with the "Scan" button first.'))
num_scans_running = self.scan_interface.num_scans_running()
if num_scans_running > 0:
if num_scans_running == 1:
text = _("There is a scan still running. Wait until it finishes and then save.")
text = _("There is a scan still running. "
"Wait until it finishes and then save.")
else:
text = _("There are %u scans still running. Wait until they finish and then save.")\
% num_scans_running
text = _("There are %u scans still running. Wait until they "
"finish and then save.") % num_scans_running
alert = HIGAlertDialog(message_format=_('Scan is running'),
secondary_text=text)
alert.run()
alert.destroy()
return
# We have multiple scans in our network inventory, so we need to display a directory
# chooser dialog
dir_chooser = SaveToDirectoryChooserDialog(title=_("Choose a directory to save scans into"))
# We have multiple scans in our network inventory, so we need to
# display a directory chooser dialog
dir_chooser = SaveToDirectoryChooserDialog(
title=_("Choose a directory to save scans into"))
if dir_chooser.run() == gtk.RESPONSE_OK:
self._save_all(self.scan_interface, dir_chooser.get_filename())
dir_chooser.destroy()
@@ -729,16 +755,20 @@ This scan has not been run yet. Start the scan with the "Scan" button first.'))
recent_scans.add_recent_scan(filename)
recent_scans.save()
def _save(self, scan_interface, saved_filename, selected_index, format = "xml"):
def _save(self, scan_interface, saved_filename, selected_index,
format="xml"):
"""Saves the scan into a file with a given filename. Displays an alert
dialog if the save fails."""
log.debug(">>> File being saved: %s" % saved_filename)
try:
scan_interface.inventory.save_to_file(saved_filename, selected_index, format)
scan_interface.inventory.get_scans()[selected_index].unsaved = False
scan_interface.inventory.save_to_file(
saved_filename, selected_index, format)
scan_interface.inventory.get_scans()[selected_index].unsaved = \
False
except (OSError, IOError), e:
alert = HIGAlertDialog(message_format=_('Can\'t save file'),
secondary_text=_('Can\'t open file to write.\n%s') % str(e))
alert = HIGAlertDialog(
message_format=_("Can't save file"),
secondary_text=_("Can't open file to write.\n%s") % str(e))
alert.run()
alert.destroy()
else:
@@ -766,12 +796,16 @@ This scan has not been run yet. Start the scan with the "Scan" button first.'))
return w
def _new_scan_profile_cb(self, p):
pe = ProfileEditor(command=self.scan_interface.command_toolbar.command, deletable=False)
pe = ProfileEditor(
command=self.scan_interface.command_toolbar.command,
deletable=False)
pe.set_scan_interface(self.scan_interface)
pe.show_all()
def _edit_scan_profile_cb(self, p):
pe = ProfileEditor(profile_name=self.scan_interface.toolbar.selected_profile,deletable=True,overwrite=True)
pe = ProfileEditor(
profile_name=self.scan_interface.toolbar.selected_profile,
deletable=True, overwrite=True)
pe.set_scan_interface(self.scan_interface)
pe.show_all()
@@ -779,18 +813,20 @@ This scan has not been run yet. Start the scan with the "Scan" button first.'))
show_help()
def _exit_cb(self, *args):
"""Closes the window, prompting for confirmation if necessary. If one of
the tabs couldn't be closed, the function returns True and doesn't exit
the application."""
"""Closes the window, prompting for confirmation if necessary. If one
of the tabs couldn't be closed, the function returns True and doesn't
exit the application."""
if self.scan_interface.changed:
log.debug("Found changes on closing window")
dialog = HIGDialog(buttons=(_('Close anyway').encode('utf-8'), gtk.RESPONSE_CLOSE,
gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
dialog = HIGDialog(
buttons=(_('Close anyway').encode('utf-8'),
gtk.RESPONSE_CLOSE, gtk.STOCK_CANCEL,
gtk.RESPONSE_CANCEL))
alert = HIGEntryLabel('<b>%s</b>' % _("Unsaved changes"))
text = HIGEntryLabel(_('The given scan has unsaved changes.\n\
What do you want to do?'))
text = HIGEntryLabel(_("The given scan has unsaved changes.\n"
"What do you want to do?"))
hbox = HIGHBox()
hbox.set_border_width(5)
hbox.set_spacing(12)
@@ -800,7 +836,8 @@ What do you want to do?'))
vbox.set_spacing(12)
image = gtk.Image()
image.set_from_stock(gtk.STOCK_DIALOG_QUESTION,gtk.ICON_SIZE_DIALOG)
image.set_from_stock(
gtk.STOCK_DIALOG_QUESTION, gtk.ICON_SIZE_DIALOG)
vbox.pack_start(alert)
vbox.pack_start(text)
@@ -822,13 +859,16 @@ What do you want to do?'))
elif self.scan_interface.num_scans_running() > 0:
log.debug("Trying to close a window with a running scan")
dialog = HIGDialog(buttons=(_('Close anyway').encode('utf-8'), gtk.RESPONSE_CLOSE,
gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
dialog = HIGDialog(
buttons=(_('Close anyway').encode('utf-8'),
gtk.RESPONSE_CLOSE, gtk.STOCK_CANCEL,
gtk.RESPONSE_CANCEL))
alert = HIGEntryLabel('<b>%s</b>' % _("Trying to close"))
text = HIGEntryLabel(_('The window you are trying to close has a scan \
running at the background.\nWhat do you want to do?'))
text = HIGEntryLabel(_(
"The window you are trying to close has a scan running in "
"the background.\nWhat do you want to do?"))
hbox = HIGHBox()
hbox.set_border_width(5)
hbox.set_spacing(12)
@@ -838,7 +878,8 @@ running at the background.\nWhat do you want to do?'))
vbox.set_spacing(12)
image = gtk.Image()
image.set_from_stock(gtk.STOCK_DIALOG_WARNING, gtk.ICON_SIZE_DIALOG)
image.set_from_stock(
gtk.STOCK_DIALOG_WARNING, gtk.ICON_SIZE_DIALOG)
vbox.pack_start(alert)
vbox.pack_start(text)
@@ -865,7 +906,8 @@ running at the background.\nWhat do you want to do?'))
entry = self.scan_interface.scan_result.scan_result_notebook.nmap_output.get_active_entry()
if entry is None:
return False
zenmapGUI.Print.run_print_operation(self.scan_interface.inventory, entry)
zenmapGUI.Print.run_print_operation(
self.scan_interface.inventory, entry)
def _quit_cb(self, *args):
"""Close all open windows."""
@@ -874,12 +916,15 @@ running at the background.\nWhat do you want to do?'))
if window._exit_cb():
break
def _load_diff_compare_cb (self, widget=None, extra=None):
"""Loads all active scans into a dictionary, passes it to the DiffWindow
constructor, and then displays the 'Compare Results' window."""
self.diff_window = DiffWindow(self.scan_interface.inventory.get_scans())
def _load_diff_compare_cb(self, widget=None, extra=None):
"""Loads all active scans into a dictionary, passes it to the
DiffWindow constructor, and then displays the 'Compare Results'
window."""
self.diff_window = DiffWindow(
self.scan_interface.inventory.get_scans())
self.diff_window.show_all()
def show_help():
import urllib
import webbrowser

View File

@@ -134,6 +134,7 @@ from zenmapGUI.higwidgets.higtables import HIGTable
from zenmapGUI.higwidgets.higlabels import HIGEntryLabel
from zenmapGUI.higwidgets.higbuttons import HIGButton, HIGToggleButton
class NmapOutputProperties(HIGDialog):
def __init__(self, nmap_output_view):
HIGDialog.__init__(self, _("Nmap Output Properties"),
@@ -164,10 +165,14 @@ class NmapOutputProperties(HIGDialog):
#############
# Properties:
self.property_names = {"details": [_("details"), "MAC Address:"],
"port_list": [_("port listing title"), "PORT STATE SERVICE"],
"open_port": [_("open port"), "22/tcp open ssh"],
"closed_port": [_("closed port"), "70/tcp closed gopher"],
"filtered_port": [_("filtered port"), "80/tcp filtered http"],
"port_list": [_("port listing title"),
"PORT STATE SERVICE"],
"open_port": [_("open port"),
"22/tcp open ssh"],
"closed_port": [_("closed port"),
"70/tcp closed gopher"],
"filtered_port": [_("filtered port"),
"80/tcp filtered http"],
"date": [_("date"), "2006-05-26 11:14 BRT"],
"hostname": [_("hostname"), "scanme.nmap.org"],
"ip": [_("ip"), "127.0.0.1"]}
@@ -182,18 +187,23 @@ class NmapOutputProperties(HIGDialog):
self.property_names[p].append(gtk.gdk.Color(*settings[4]))
self.property_names[p].append(settings[5])
# Creating properties and related widgets and attaching it to main table
# Creating properties and related widgets and attaching it to main
# table
y1 = 0
y2 = 1
for p in self.property_names:
hp = HighlightProperty(p, self.property_names[p])
self.highlight_main_table.attach(hp.property_name_label, 0, 1, y1, y2)
self.highlight_main_table.attach(
hp.property_name_label, 0, 1, y1, y2)
self.highlight_main_table.attach(hp.example_label, 1, 2, y1, y2)
self.highlight_main_table.attach(hp.bold_tg_button, 2, 3, y1, y2)
self.highlight_main_table.attach(hp.italic_tg_button, 3, 4, y1, y2)
self.highlight_main_table.attach(hp.underline_tg_button, 4, 5, y1, y2)
self.highlight_main_table.attach(hp.text_color_button, 5, 6, y1, y2)
self.highlight_main_table.attach(hp.highlight_color_button, 6, 7, y1, y2)
self.highlight_main_table.attach(
hp.underline_tg_button, 4, 5, y1, y2)
self.highlight_main_table.attach(
hp.text_color_button, 5, 6, y1, y2)
self.highlight_main_table.attach(
hp.highlight_color_button, 6, 7, y1, y2)
# Setting example styles and colors
hp.update_example()
@@ -203,13 +213,13 @@ class NmapOutputProperties(HIGDialog):
y1 += 1
y2 += 1
# Packing main table into main vbox
self.highlight_main_vbox.pack_start(self.highlight_main_table)
# Adding color tab
self.properties_notebook.append_page(self.highlight_main_vbox,
gtk.Label(_("Highlight definitions")))
self.properties_notebook.append_page(
self.highlight_main_vbox,
gtk.Label(_("Highlight definitions")))
class HighlightProperty(object):
@@ -235,8 +245,10 @@ class HighlightProperty(object):
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)
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)
@@ -244,20 +256,23 @@ class HighlightProperty(object):
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)
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 = 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.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()
@@ -272,18 +287,21 @@ class HighlightProperty(object):
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 = 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.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.connect(
"delete-event", self.highlight_color_dialog_close,
color_dialog)
color_dialog.run()
@@ -304,8 +322,9 @@ class HighlightProperty(object):
attributes = pango.AttrList()
attributes.insert(pango.AttrForeground(self.text_color.red, self.text_color.green,
self.text_color.blue, start, end))
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,
@@ -315,7 +334,8 @@ class HighlightProperty(object):
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))
attributes.insert(
pango.AttrWeight(pango.WEIGHT_NORMAL, start, end))
# Italic verification
if self.italic_tg_button.get_active():
@@ -325,13 +345,14 @@ class HighlightProperty(object):
# Underline verification
if self.underline_tg_button.get_active():
attributes.insert(pango.AttrUnderline(pango.UNDERLINE_SINGLE, start, end))
attributes.insert(
pango.AttrUnderline(pango.UNDERLINE_SINGLE, start, end))
else:
attributes.insert(pango.AttrUnderline(pango.UNDERLINE_NONE, start, end))
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("<>")

View File

@@ -134,13 +134,14 @@ from zenmapCore.UmitConf import NmapOutputHighlight
from zenmapGUI.NmapOutputProperties import NmapOutputProperties
class NmapOutputViewer (gtk.VBox):
HIGHLIGHT_PROPERTIES = ["details", "date", "hostname", "ip", "port_list",
"open_port", "closed_port", "filtered_port"]
def __init__ (self, refresh=1, stop=1):
def __init__(self, refresh=1, stop=1):
self.nmap_highlight = NmapOutputHighlight()
gtk.VBox.__init__ (self)
gtk.VBox.__init__(self)
# Creating widgets
self.__create_widgets()
@@ -158,7 +159,7 @@ class NmapOutputViewer (gtk.VBox):
self.refreshing = True
# Adding widgets to the VBox
self.pack_start(self.scrolled, expand = True, fill = True)
self.pack_start(self.scrolled, expand=True, fill=True)
# The NmapCommand instance, if any, whose output is shown in this
# display.
@@ -166,16 +167,16 @@ class NmapOutputViewer (gtk.VBox):
# The position of the last read from the output stream.
self.output_file_pointer = None
def __create_widgets (self):
def __create_widgets(self):
# Creating widgets
self.scrolled = gtk.ScrolledWindow ()
self.text_view = gtk.TextView ()
self.scrolled = gtk.ScrolledWindow()
self.text_view = gtk.TextView()
def __set_scrolled_window (self):
def __set_scrolled_window(self):
# Seting scrolled window
self.scrolled.set_border_width (5)
self.scrolled.set_border_width(5)
self.scrolled.add(self.text_view)
self.scrolled.set_policy (gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
self.scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
def __set_text_view(self):
self.text_view.set_wrap_mode(gtk.WRAP_WORD)
@@ -205,8 +206,12 @@ class NmapOutputViewer (gtk.VBox):
text_color = settings[3]
highlight_color = settings[4]
tag.set_property("foreground", gtk.color_selection_palette_to_string([gtk.gdk.Color(*text_color),]))
tag.set_property("background", gtk.color_selection_palette_to_string([gtk.gdk.Color(*highlight_color),]))
tag.set_property(
"foreground", gtk.color_selection_palette_to_string(
[gtk.gdk.Color(*text_color), ]))
tag.set_property(
"background", gtk.color_selection_palette_to_string(
[gtk.gdk.Color(*highlight_color), ]))
def go_to_host(self, host):
"""Go to host line on nmap output result"""
@@ -218,7 +223,8 @@ class NmapOutputViewer (gtk.VBox):
for i in xrange(len(output)):
if re_host.match(output[i]):
self.text_view.scroll_to_iter(buff.get_iter_at_line(i), 0, True, 0, 0)
self.text_view.scroll_to_iter(
buff.get_iter_at_line(i), 0, True, 0, 0)
break
def show_output_properties(self, widget):
@@ -259,7 +265,7 @@ class NmapOutputViewer (gtk.VBox):
self.nmap_highlight.save_changes()
self.apply_highlighting()
def apply_highlighting(self, start_iter = None, end_iter = None):
def apply_highlighting(self, start_iter=None, end_iter=None):
buf = self.text_view.get_buffer()
if start_iter is None:
@@ -302,7 +308,7 @@ class NmapOutputViewer (gtk.VBox):
self.output_file_pointer = None
self.refresh_output()
def refresh_output(self, widget = None):
def refresh_output(self, widget=None):
"""Update the output from the latest output of the command associated
with this view, as set by set_command_execution. It has no effect if no
command has been set."""
@@ -316,7 +322,8 @@ class NmapOutputViewer (gtk.VBox):
pos = self.command_execution.stdout_file.tell()
new_output = self.command_execution.stdout_file.read()
self.output_file_pointer = self.command_execution.stdout_file.tell()
# print "read %d -> %d %d" % (pos, self.output_file_pointer, len(new_output))
# print "read %d -> %d %d" % (
# pos, self.output_file_pointer, len(new_output))
v_adj = self.scrolled.get_vadjustment()
if new_output and v_adj is not None:
@@ -324,15 +331,19 @@ class NmapOutputViewer (gtk.VBox):
at_end = (v_adj.value >= v_adj.upper - v_adj.page_size)
buf = self.text_view.get_buffer()
prev_end_mark = buf.create_mark(None, buf.get_end_iter(), left_gravity = True)
prev_end_mark = buf.create_mark(
None, buf.get_end_iter(), left_gravity=True)
buf.insert(buf.get_end_iter(), new_output)
# Highlight the new text.
self.apply_highlighting(buf.get_iter_at_mark(prev_end_mark), buf.get_end_iter())
self.apply_highlighting(
buf.get_iter_at_mark(prev_end_mark), buf.get_end_iter())
if at_end:
# If we were already scrolled to the bottom, scroll back to the
# bottom again. Also do it in an idle handler in case the added
# text causes a scroll bar to appear and reflow the text, making
# the text a bit taller.
# text causes a scroll bar to appear and reflow the text,
# making the text a bit taller.
self.text_view.scroll_mark_onscreen(self.end_mark)
gobject.idle_add(lambda: self.text_view.scroll_mark_onscreen(self.end_mark))
gobject.idle_add(
lambda: self.text_view.scroll_mark_onscreen(
self.end_mark))

View File

@@ -138,6 +138,7 @@ import zenmapCore.I18N
from zenmapCore.UmitLogging import log
from zenmapGUI.ScriptInterface import *
def get_option_check_auxiliary_widget(option, ops, check):
if option in ("-sI", "-b", "--script", "--script-args", "--exclude", "-p",
"-D", "-S", "--source-port", "-e", "--ttl", "-iR", "--max-retries",
@@ -159,6 +160,7 @@ def get_option_check_auxiliary_widget(option, ops, check):
else:
assert False, "Unknown option %s" % option
class OptionEntry(gtk.Entry):
def __init__(self, option, ops, check):
gtk.Entry.__init__(self)
@@ -187,6 +189,7 @@ class OptionEntry(gtk.Entry):
self.check.set_active(True)
self.ops[self.option] = self.get_text().decode("UTF-8")
class OptionExtras(gtk.Entry):
def __init__(self, option, ops, check):
gtk.Entry.__init__(self)
@@ -214,6 +217,7 @@ class OptionExtras(gtk.Entry):
self.check.set_active(True)
self.ops.extras = [self.get_text().decode("UTF-8")]
class OptionLevel(gtk.SpinButton):
def __init__(self, option, ops, check):
gtk.SpinButton.__init__(self, gtk.Adjustment(0, 0, 10, 1), 0.0, 0)
@@ -243,6 +247,7 @@ class OptionLevel(gtk.SpinButton):
self.check.set_active(True)
self.ops[self.option] = int(self.get_adjustment().get_value())
class OptionFile(gtk.HBox):
__gsignals__ = {
"changed": (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ())
@@ -257,7 +262,7 @@ class OptionFile(gtk.HBox):
self.entry = gtk.Entry()
self.pack_start(self.entry, True, True)
button = HIGButton(stock = gtk.STOCK_OPEN)
button = HIGButton(stock=gtk.STOCK_OPEN)
self.pack_start(button, False)
button.connect("clicked", self.clicked_cb)
@@ -291,6 +296,7 @@ class OptionFile(gtk.HBox):
self.entry.set_text(dialog.get_filename())
dialog.destroy()
class TargetEntry(gtk.Entry):
def __init__(self, ops):
gtk.Entry.__init__(self)
@@ -307,11 +313,12 @@ class TargetEntry(gtk.Entry):
def get_targets(self):
return split_quoted(self.get_text().decode("UTF-8"))
class OptionTab(object):
def __init__(self, root_tab, ops, update_command, help_buf):
actions = {'target':self.__parse_target,
'option_list':self.__parse_option_list,
'option_check':self.__parse_option_check}
actions = {'target': self.__parse_target,
'option_list': self.__parse_option_list,
'option_check': self.__parse_option_check}
self.ops = ops
self.update_command = update_command
@@ -321,8 +328,10 @@ class OptionTab(object):
self.notscripttab = False # assume every tab is scripting tab
self.widgets_list = []
for option_element in root_tab.childNodes:
try:option_element.tagName
except:pass
try:
option_element.tagName
except:
pass
else:
if option_element.tagName in actions.keys():
parse_func = actions[option_element.tagName]
@@ -339,7 +348,8 @@ class OptionTab(object):
def __parse_option_list(self, option_list_element):
children = option_list_element.getElementsByTagName(u'option')
label_widget = HIGEntryLabel(_(option_list_element.getAttribute(u'label')))
label_widget = HIGEntryLabel(
_(option_list_element.getAttribute(u'label')))
option_list_widget = OptionList(self.ops)
for child in children:
@@ -348,8 +358,10 @@ class OptionTab(object):
label = _(child.getAttribute(u'label'))
option_list_widget.append(option, argument, label)
self.profilehelp.add_label(option, label)
self.profilehelp.add_shortdesc(option, _(child.getAttribute(u'short_desc')))
self.profilehelp.add_example(option, child.getAttribute(u'example'))
self.profilehelp.add_shortdesc(
option, _(child.getAttribute(u'short_desc')))
self.profilehelp.add_example(
option, child.getAttribute(u'example'))
option_list_widget.update()
@@ -369,10 +381,12 @@ class OptionTab(object):
self.profilehelp.add_example(option, example)
check = OptionCheck(option, label)
auxiliary_widget = get_option_check_auxiliary_widget(option, self.ops, check)
auxiliary_widget = get_option_check_auxiliary_widget(
option, self.ops, check)
if auxiliary_widget is not None:
auxiliary_widget.connect("changed", self.update_auxiliary_widget)
auxiliary_widget.connect('enter-notify-event', self.enter_notify_event_cb, option)
auxiliary_widget.connect(
'enter-notify-event', self.enter_notify_event_cb, option)
else:
check.set_active(not not self.ops[option])
@@ -381,14 +395,14 @@ class OptionTab(object):
return check, auxiliary_widget
def fill_table(self, table, expand_fill = True):
def fill_table(self, table, expand_fill=True):
yopt = (0, gtk.EXPAND | gtk.FILL)[expand_fill]
for y, widget in enumerate(self.widgets_list):
if widget[1] == None:
table.attach(widget[0], 0, 2, y, y+1, yoptions=yopt)
table.attach(widget[0], 0, 2, y, y + 1, yoptions=yopt)
else:
table.attach(widget[0], 0, 1, y, y+1, yoptions=yopt)
table.attach(widget[1], 1, 2, y, y+1, yoptions=yopt)
table.attach(widget[0], 0, 1, y, y + 1, yoptions=yopt)
table.attach(widget[1], 1, 2, y, y + 1, yoptions=yopt)
def update_auxiliary_widget(self, auxiliary_widget):
self.update_command()
@@ -446,6 +460,7 @@ class OptionTab(object):
def enter_notify_event_cb(self, event, widget, option):
self.show_help_for_option(option)
class OptionBuilder(object):
def __init__(self, xml_file, ops, update_func, help_buf):
"""
@@ -463,7 +478,6 @@ class OptionBuilder(object):
self.root_tag = "interface"
self.xml = self.xml.getElementsByTagName(self.root_tag)[0]
self.groups = self.__parse_groups()
@@ -490,11 +504,13 @@ class OptionBuilder(object):
dic = {}
for tab_name in self.groups:
if tab_name != "Scripting":
dic[tab_name] = OptionTab(self.xml.getElementsByTagName(tab_name)[0],
self.ops, self.update_func, self.help_buf)
dic[tab_name] = OptionTab(
self.xml.getElementsByTagName(tab_name)[0], self.ops,
self.update_func, self.help_buf)
dic[tab_name].notscripttab = True
else:
dic[tab_name] =ScriptInterface(None,self.ops, self.update_func, self.help_buf)
dic[tab_name] = ScriptInterface(
None, self.ops, self.update_func, self.help_buf)
return dic
@@ -518,7 +534,8 @@ class OptionList(gtk.ComboBox):
opt, arg = row[0], row[1]
if opt == "":
continue
if (not arg and self.ops[opt]) or (arg and str(self.ops[opt]) == arg):
if ((not arg and self.ops[opt]) or
(arg and str(self.ops[opt]) == arg)):
selected = i
self.set_active(selected)
@@ -535,6 +552,7 @@ class OptionList(gtk.ComboBox):
self.list.append([option, argument, opt])
self.options.append(option)
class OptionCheck(gtk.CheckButton):
def __init__(self, option, label):
opt = label

View File

@@ -123,8 +123,8 @@
# This prints the normal (text) output of a single scan. Ideas for further
# development:
#
# Print the topology graphic. The graphic is already made with Cairo so the same
# code can be used to draw on the print context.
# Print the topology graphic. The graphic is already made with Cairo so the
# same code can be used to draw on the print context.
#
# Print in color with highlighting, like NmapOutputViewer.
#
@@ -139,6 +139,7 @@ import pango
MONOSPACE_FONT_DESC = pango.FontDescription("Monospace 12")
class PrintState (object):
"""This is the userdatum passed to gtk.PrintOperation callbacks."""
@@ -169,7 +170,9 @@ class PrintState (object):
op.set_n_pages((len(self.lines) - 1) / self.lines_per_page + 1)
def draw_page(self, op, context, page_nr):
this_page_lines = self.lines[page_nr * self.lines_per_page:(page_nr + 1) * self.lines_per_page]
this_page_lines = self.lines[
page_nr * self.lines_per_page:
(page_nr + 1) * self.lines_per_page]
layout = context.create_pango_layout()
# Do no wrapping.
layout.set_width(-1)
@@ -180,6 +183,7 @@ class PrintState (object):
cr = context.get_cairo_context()
cr.show_layout(layout)
def run_print_operation(inventory, entry):
op = gtk.PrintOperation()
state = PrintState(inventory, entry)

View File

@@ -125,6 +125,7 @@ import gtk
from zenmapCore.UmitConf import CommandProfile
import zenmapCore.I18N
class ProfileCombo(gtk.ComboBoxEntry, object):
def __init__(self):
gtk.ComboBoxEntry.__init__(self, gtk.ListStore(str), 0)

View File

@@ -123,7 +123,8 @@
import gtk
from zenmapGUI.higwidgets.higwindows import HIGWindow
from zenmapGUI.higwidgets.higboxes import HIGVBox, HIGHBox, HIGSpacer, hig_box_space_holder
from zenmapGUI.higwidgets.higboxes import HIGVBox, HIGHBox, HIGSpacer, \
hig_box_space_holder
from zenmapGUI.higwidgets.higlabels import HIGSectionLabel, HIGEntryLabel
from zenmapGUI.higwidgets.higscrollers import HIGScrolledWindow
from zenmapGUI.higwidgets.higtextviewers import HIGTextView
@@ -137,8 +138,10 @@ from zenmapCore.UmitLogging import log
import zenmapCore.I18N
from zenmapCore.NmapOptions import NmapOptions
class ProfileEditor(HIGWindow):
def __init__(self, command=None, profile_name=None, deletable=True, overwrite=False):
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'))
@@ -148,8 +151,8 @@ class ProfileEditor(HIGWindow):
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.
# 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()
@@ -164,20 +167,27 @@ class ProfileEditor(HIGWindow):
# Interface settings
self.profile_name_entry.set_text(profile_name)
self.profile_description_text.get_buffer().set_text(prof['description'])
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())
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 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.__create_tab(
_(tab),
_(self.option_builder.section_names[tab]),
self.option_builder.tabs[tab])
self.update_command()
@@ -195,16 +205,18 @@ class ProfileEditor(HIGWindow):
# 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)
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.")
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.")
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):
@@ -218,8 +230,8 @@ class ProfileEditor(HIGWindow):
#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.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)
@@ -231,12 +243,14 @@ class ProfileEditor(HIGWindow):
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_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)
self.profile_description_text.connect(
'motion-notify-event', self.update_help_desc)
# Buttons
self.buttons_hbox = HIGHBox()
@@ -259,8 +273,9 @@ class ProfileEditor(HIGWindow):
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)
self.help_vbox.set_size_request(200, -1)
###
def __pack_widgets(self):
###
@@ -283,9 +298,9 @@ class ProfileEditor(HIGWindow):
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.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)
@@ -300,10 +315,11 @@ class ProfileEditor(HIGWindow):
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)
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())
@@ -327,7 +343,7 @@ class ProfileEditor(HIGWindow):
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
if tab.notscripttab: # if notscripttab is set
table = HIGTable()
table.set_row_spacings(2)
section = HIGSectionLabel(section_name)
@@ -337,7 +353,7 @@ class ProfileEditor(HIGWindow):
tab.fill_table(table, True)
else:
hbox = tab.get_hmain_box()
vbox.pack_start(hbox,True,True,0)
vbox.pack_start(hbox, True, True, 0)
self.notebook.append_page(vbox, gtk.Label(tab_name))
def save_profile(self, widget):
@@ -345,9 +361,10 @@ class ProfileEditor(HIGWindow):
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 = HIGAlertDialog(
message_format=_('Unnamed profile'),
secondary_text=_(
'You must provide a name for this profile.'))
alert.run()
alert.destroy()
@@ -366,11 +383,12 @@ for this profile.'))
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 = 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
@@ -392,9 +410,10 @@ name.' % profile_name))
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.'))
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)
@@ -404,7 +423,8 @@ name.' % profile_name))
vbox.set_spacing(12)
image = gtk.Image()
image.set_from_stock(gtk.STOCK_DIALOG_WARNING, gtk.ICON_SIZE_DIALOG)
image.set_from_stock(
gtk.STOCK_DIALOG_WARNING, gtk.ICON_SIZE_DIALOG)
vbox.pack_start(alert)
vbox.pack_start(text)
@@ -433,7 +453,7 @@ name.' % profile_name))
self.scan_interface.toolbar.profile_entry.update()
list = self.scan_interface.toolbar.profile_entry.get_model()
length = len(list)
if length >0 :
if length > 0:
self.scan_interface.toolbar.profile_entry.set_active(0)

View File

@@ -122,6 +122,7 @@
from zenmapCore.UmitLogging import log
class ProfileHelp:
def __init__(self, currentstate=None):
self.currentstate = "Default"
@@ -139,7 +140,7 @@ class ProfileHelp:
if self.currentstate in self.labels.keys():
return self.labels[self.currentstate]
else:
return "" #blank
return "" # blank
def add_shortdesc(self, option_name, text):
self.descs[option_name] = text
@@ -148,7 +149,7 @@ class ProfileHelp:
if self.currentstate in self.descs.keys():
return self.descs[self.currentstate]
else:
return "" #blank
return "" # blank
def add_example(self, option_name, text):
self.examples[option_name] = text
@@ -157,8 +158,8 @@ class ProfileHelp:
if self.currentstate in self.examples.keys():
return self.examples[self.currentstate]
else:
return "" #blank
return "" # blank
def handler(self,whichLabel):
def handler(self, whichLabel):
log.debug("whichLabel: %s" % whichLabel)
self.currentstate = whichLabel

View File

@@ -123,7 +123,8 @@
import gtk
from zenmapGUI.higwidgets.higexpanders import HIGExpander
from zenmapGUI.higwidgets.higboxes import HIGVBox, HIGHBox, hig_box_space_holder
from zenmapGUI.higwidgets.higboxes import HIGVBox, HIGHBox,\
hig_box_space_holder
from zenmapGUI.higwidgets.higlabels import HIGEntryLabel
from zenmapGUI.higwidgets.higtables import HIGTable
from zenmapGUI.Icons import get_os_logo, get_vulnerability_logo
@@ -132,6 +133,7 @@ import zenmapCore.I18N
na = _('Not available')
class ScanHostDetailsPage(HIGExpander):
def __init__(self, host):
HIGExpander.__init__(self, host.get_hostname())
@@ -139,6 +141,7 @@ class ScanHostDetailsPage(HIGExpander):
self.host_details = HostDetails(host)
self.hbox._pack_expand_fill(self.host_details)
class HostDetails(HIGVBox):
def __init__(self, host):
HIGVBox.__init__(self)
@@ -147,7 +150,8 @@ class HostDetails(HIGVBox):
self.set_os_image(get_os_logo(host))
self.set_vulnerability_image(get_vulnerability_logo(host.get_open_ports()))
self.set_vulnerability_image(
get_vulnerability_logo(host.get_open_ports()))
self.set_host_status({'state': host.get_state(),
'open': str(host.get_open_ports()),
@@ -179,16 +183,19 @@ class HostDetails(HIGVBox):
self.set_comment(host.comment)
def __create_widgets(self):
self.host_status_expander = gtk.Expander('<b>'+_('Host Status')+'</b>')
self.address_expander = gtk.Expander('<b>'+_('Addresses')+'</b>')
self.hostnames_expander = gtk.Expander('<b>'+_('Hostnames')+'</b>')
self.os_expander = gtk.Expander('<b>'+_('Operating System')+'</b>')
self.portsused_expander = gtk.Expander('<b>'+_('Ports used')+'</b>')
self.osclass_expander = gtk.Expander('<b>'+_('OS Classes')+'</b>')
self.tcp_expander = gtk.Expander('<b>'+_('TCP Sequence')+'</b>')
self.ip_expander = gtk.Expander('<b>'+_('IP ID Sequence')+'</b>')
self.tcpts_expander = gtk.Expander('<b>'+_('TCP TS Sequence')+'</b>')
self.comment_expander = gtk.Expander('<b>'+_('Comments')+'</b>')
self.host_status_expander = gtk.Expander(
'<b>' + _('Host Status') + '</b>')
self.address_expander = gtk.Expander('<b>' + _('Addresses') + '</b>')
self.hostnames_expander = gtk.Expander('<b>' + _('Hostnames') + '</b>')
self.os_expander = gtk.Expander('<b>' + _('Operating System') + '</b>')
self.portsused_expander = gtk.Expander(
'<b>' + _('Ports used') + '</b>')
self.osclass_expander = gtk.Expander('<b>' + _('OS Classes') + '</b>')
self.tcp_expander = gtk.Expander('<b>' + _('TCP Sequence') + '</b>')
self.ip_expander = gtk.Expander('<b>' + _('IP ID Sequence') + '</b>')
self.tcpts_expander = gtk.Expander(
'<b>' + _('TCP TS Sequence') + '</b>')
self.comment_expander = gtk.Expander('<b>' + _('Comments') + '</b>')
self.os_image = gtk.Image()
self.vulnerability_image = gtk.Image()
@@ -214,7 +221,6 @@ class HostDetails(HIGVBox):
self.lastboot_label = HIGEntryLabel(_('Last boot:'))
self.info_lastboot_label = HIGEntryLabel(na)
# Addresses expander
self.ipv4_label = HIGEntryLabel(_('IPv4:'))
self.info_ipv4_label = HIGEntryLabel(na)
@@ -243,63 +249,78 @@ class HostDetails(HIGVBox):
table, hbox = self.create_table_hbox()
try:
if status['state'] == '': raise Exception
if status['state'] == '':
raise Exception
self.info_host_state_label.set_text(status['state'])
except:pass
except:
pass
try:
if status['open'] == '': raise Exception
if status['open'] == '':
raise Exception
self.info_open_ports.set_text(status['open'])
except:pass
except:
pass
try:
if status['filtered'] == '': raise Exception
if status['filtered'] == '':
raise Exception
self.info_filtered_label.set_text(status['filtered'])
except:pass
except:
pass
try:
if status['closed'] == '': raise Exception
if status['closed'] == '':
raise Exception
self.info_closed_ports.set_text(status['closed'])
except:pass
except:
pass
try:
if status['scanned'] == '': raise Exception
if status['scanned'] == '':
raise Exception
self.info_scanned_label.set_text(status['scanned'])
except:pass
except:
pass
try:
if status['uptime'] == '': raise Exception
if status['uptime'] == '':
raise Exception
self.info_uptime_label.set_text(status['uptime'])
except:pass
except:
pass
try:
if status['lastboot'] == '': raise Exception
if status['lastboot'] == '':
raise Exception
self.info_lastboot_label.set_text(status['lastboot'])
except:pass
except:
pass
table.attach(self.host_state_label,0,1,0,1)
table.attach(self.info_host_state_label,1,2,0,1)
table.attach(self.host_state_label, 0, 1, 0, 1)
table.attach(self.info_host_state_label, 1, 2, 0, 1)
table.attach(self.open_label,0,1,1,2)
table.attach(self.info_open_ports,1,2,1,2)
table.attach(self.open_label, 0, 1, 1, 2)
table.attach(self.info_open_ports, 1, 2, 1, 2)
table.attach(self.filtered_label,0,1,2,3)
table.attach(self.info_filtered_label,1,2,2,3)
table.attach(self.filtered_label, 0, 1, 2, 3)
table.attach(self.info_filtered_label, 1, 2, 2, 3)
table.attach(self.closed_label,0,1,3,4)
table.attach(self.info_closed_ports,1,2,3,4)
table.attach(self.closed_label, 0, 1, 3, 4)
table.attach(self.info_closed_ports, 1, 2, 3, 4)
table.attach(self.scanned_label,0,1,4,5)
table.attach(self.info_scanned_label,1,2,4,5)
table.attach(self.scanned_label, 0, 1, 4, 5)
table.attach(self.info_scanned_label, 1, 2, 4, 5)
table.attach(self.uptime_label,0,1,5,6)
table.attach(self.info_uptime_label,1,2,5,6)
table.attach(self.uptime_label, 0, 1, 5, 6)
table.attach(self.info_uptime_label, 1, 2, 5, 6)
table.attach(self.lastboot_label,0,1,6,7)
table.attach(self.info_lastboot_label,1,2,6,7)
table.attach(self.lastboot_label, 0, 1, 6, 7)
table.attach(self.info_lastboot_label, 1, 2, 6, 7)
table.attach(self.os_image,2,4,0,3,xoptions=1,yoptions=0)
table.attach(self.vulnerability_image,2,4,4,7,xoptions=1,yoptions=0)
table.attach(self.os_image, 2, 4, 0, 3, xoptions=1, yoptions=0)
table.attach(
self.vulnerability_image, 2, 4, 4, 7, xoptions=1, yoptions=0)
table.set_col_spacing(1, 50)
@@ -307,10 +328,10 @@ class HostDetails(HIGVBox):
self._pack_noexpand_nofill(self.host_status_expander)
def set_os_image(self, image):
self.os_image.set_from_stock(image,gtk.ICON_SIZE_DIALOG)
self.os_image.set_from_stock(image, gtk.ICON_SIZE_DIALOG)
def set_vulnerability_image(self, image):
self.vulnerability_image.set_from_stock(image,gtk.ICON_SIZE_DIALOG)
self.vulnerability_image.set_from_stock(image, gtk.ICON_SIZE_DIALOG)
def set_addresses(self, address):
self.address_expander.set_use_markup(True)
@@ -319,28 +340,34 @@ class HostDetails(HIGVBox):
#print '>>> Address:', address
try:
if address['ipv4'] == 1: raise Exception
if address['ipv4'] == 1:
raise Exception
self.info_ipv4_label.set_text(address['ipv4'])
except:pass
except:
pass
try:
if address['ipv6'] == 1: raise Exception
if address['ipv6'] == 1:
raise Exception
self.info_ipv6_label.set_text(address['ipv6'])
except:pass
except:
pass
try:
if address['mac'] == 1: raise Exception
if address['mac'] == 1:
raise Exception
self.info_mac_label.set_text(address['mac'])
except:pass
except:
pass
table.attach(self.ipv4_label,0,1,0,1)
table.attach(self.info_ipv4_label,1,2,0,1)
table.attach(self.ipv4_label, 0, 1, 0, 1)
table.attach(self.info_ipv4_label, 1, 2, 0, 1)
table.attach(self.ipv6_label,0,1,1,2)
table.attach(self.info_ipv6_label,1,2,1,2)
table.attach(self.ipv6_label, 0, 1, 1, 2)
table.attach(self.info_ipv6_label, 1, 2, 1, 2)
table.attach(self.mac_label,0,1,2,3)
table.attach(self.info_mac_label,1,2,2,3)
table.attach(self.mac_label, 0, 1, 2, 3)
table.attach(self.info_mac_label, 1, 2, 2, 3)
self.address_expander.add(hbox)
self._pack_noexpand_nofill(self.address_expander)
@@ -356,17 +383,21 @@ class HostDetails(HIGVBox):
for h in hostname:
name = na
try:name = h['hostname']
except:pass
try:
name = h['hostname']
except:
pass
type = na
try:type = h['hostname_type']
except:pass
try:
type = h['hostname_type']
except:
pass
table.attach(HIGEntryLabel(_('Name - Type:')),0,1,y1,y2)
table.attach(HIGEntryLabel(name+' - '+\
type),1,2,y1,y2)
y1+=1;y2+=1
table.attach(HIGEntryLabel(_('Name - Type:')), 0, 1, y1, y2)
table.attach(HIGEntryLabel(name + ' - ' + type), 1, 2, y1, y2)
y1 += 1
y2 += 1
self.hostnames_expander.add(hbox)
self._pack_noexpand_nofill(self.hostnames_expander)
@@ -379,29 +410,34 @@ class HostDetails(HIGVBox):
progress = gtk.ProgressBar()
try:
progress.set_fraction(float(os['accuracy'])/100.0)
progress.set_text(os['accuracy']+'%')
except:progress.set_text(_('Not Available'))
progress.set_fraction(float(os['accuracy']) / 100.0)
progress.set_text(os['accuracy'] + '%')
except:
progress.set_text(_('Not Available'))
table.attach(HIGEntryLabel(_('Name:')),0,1,0,1)
table.attach(HIGEntryLabel(os['name']),1,2,0,1)
table.attach(HIGEntryLabel(_('Name:')), 0, 1, 0, 1)
table.attach(HIGEntryLabel(os['name']), 1, 2, 0, 1)
table.attach(HIGEntryLabel(_('Accuracy:')),0,1,1,2)
table.attach(progress,1,2,1,2)
table.attach(HIGEntryLabel(_('Accuracy:')), 0, 1, 1, 2)
table.attach(progress, 1, 2, 1, 2)
y1=2;y2=3
y1 = 2
y2 = 3
try:
self.set_ports_used(os['portsused'])
table.attach(self.portsused_expander,0,2,y1,y2)
y1+=1;y2+=1
except:pass
table.attach(self.portsused_expander, 0, 2, y1, y2)
y1 += 1
y2 += 1
except:
pass
try:
self.set_osclass(os['osclasses'])
self.osclass_expander.set_use_markup(True)
table.attach(self.osclass_expander,0,2,y1,y2)
except:pass
table.attach(self.osclass_expander, 0, 2, y1, y2)
except:
pass
self.os_expander.add(hbox)
self._pack_noexpand_nofill(self.os_expander)
@@ -410,13 +446,17 @@ class HostDetails(HIGVBox):
self.portsused_expander.set_use_markup(True)
table, hbox = self.create_table_hbox()
y1=0;y2=1
y1 = 0
y2 = 1
for p in ports:
table.attach(HIGEntryLabel(_('Port-Protocol-State:')),0,1,y1,y2)
table.attach(HIGEntryLabel(p['portid']+' - '+p['proto']+' - '+\
p['state']),1,2,y1,y2)
y1+=1;y2+=1
table.attach(HIGEntryLabel(
_('Port-Protocol-State:')), 0, 1, y1, y2)
table.attach(HIGEntryLabel(
p['portid'] + ' - ' + p['proto'] + ' - ' + p['state']
), 1, 2, y1, y2)
y1 += 1
y2 += 1
self.portsused_expander.add(hbox)
@@ -425,25 +465,27 @@ class HostDetails(HIGVBox):
self.osclass_expander.set_use_markup(True)
table, hbox = self.create_table_hbox()
table.attach(HIGEntryLabel(_('Type')),0,1,0,1)
table.attach(HIGEntryLabel(_('Vendor')),1,2,0,1)
table.attach(HIGEntryLabel(_('OS Family')),2,3,0,1)
table.attach(HIGEntryLabel(_('OS Generation')),3,4,0,1)
table.attach(HIGEntryLabel(_('Accuracy')),4,5,0,1)
table.attach(HIGEntryLabel(_('Type')), 0, 1, 0, 1)
table.attach(HIGEntryLabel(_('Vendor')), 1, 2, 0, 1)
table.attach(HIGEntryLabel(_('OS Family')), 2, 3, 0, 1)
table.attach(HIGEntryLabel(_('OS Generation')), 3, 4, 0, 1)
table.attach(HIGEntryLabel(_('Accuracy')), 4, 5, 0, 1)
y1=1;y2=2
y1 = 1
y2 = 2
for o in osclass:
table.attach(HIGEntryLabel(o['type']),0,1,y1,y2)
table.attach(HIGEntryLabel(o['vendor']),1,2,y1,y2)
table.attach(HIGEntryLabel(o['osfamily']),2,3,y1,y2)
table.attach(HIGEntryLabel(o['osgen']),3,4,y1,y2)
table.attach(HIGEntryLabel(o['type']), 0, 1, y1, y2)
table.attach(HIGEntryLabel(o['vendor']), 1, 2, y1, y2)
table.attach(HIGEntryLabel(o['osfamily']), 2, 3, y1, y2)
table.attach(HIGEntryLabel(o['osgen']), 3, 4, y1, y2)
progress = gtk.ProgressBar()
progress.set_text(o['accuracy']+'%')
progress.set_fraction(float(o['accuracy'])/100.0)
table.attach(progress,4,5,y1,y2)
y1+=1;y2+=1
progress.set_text(o['accuracy'] + '%')
progress.set_fraction(float(o['accuracy']) / 100.0)
table.attach(progress, 4, 5, y1, y2)
y1 += 1
y2 += 1
self.osclass_expander.add(hbox)
@@ -456,14 +498,14 @@ class HostDetails(HIGVBox):
for v in tcpseq['values'].split(','):
combo.append_text(v)
table.attach(HIGEntryLabel(_('Difficulty:')),0,1,1,2)
table.attach(HIGEntryLabel(tcpseq['difficulty']),1,2,1,2)
table.attach(HIGEntryLabel(_('Difficulty:')), 0, 1, 1, 2)
table.attach(HIGEntryLabel(tcpseq['difficulty']), 1, 2, 1, 2)
table.attach(HIGEntryLabel(_('Index:')),0,1,2,3)
table.attach(HIGEntryLabel(tcpseq['index']),1,2,2,3)
table.attach(HIGEntryLabel(_('Index:')), 0, 1, 2, 3)
table.attach(HIGEntryLabel(tcpseq['index']), 1, 2, 2, 3)
table.attach(HIGEntryLabel(_('Values:')),0,1,3,4)
table.attach(combo,1,2,3,4)
table.attach(HIGEntryLabel(_('Values:')), 0, 1, 3, 4)
table.attach(combo, 1, 2, 3, 4)
self.tcp_expander.add(hbox)
self._pack_noexpand_nofill(self.tcp_expander)
@@ -478,11 +520,11 @@ class HostDetails(HIGVBox):
for i in ipseq['values'].split(','):
combo.append_text(i)
table.attach(HIGEntryLabel(_('Class:')),0,1,0,1)
table.attach(HIGEntryLabel(ipseq['class']),1,2,0,1)
table.attach(HIGEntryLabel(_('Class:')), 0, 1, 0, 1)
table.attach(HIGEntryLabel(ipseq['class']), 1, 2, 0, 1)
table.attach(HIGEntryLabel(_('Values:')),0,1,1,2)
table.attach(combo,1,2,1,2)
table.attach(HIGEntryLabel(_('Values:')), 0, 1, 1, 2)
table.attach(combo, 1, 2, 1, 2)
self.ip_expander.add(hbox)
self._pack_noexpand_nofill(self.ip_expander)
@@ -497,11 +539,11 @@ class HostDetails(HIGVBox):
for i in tcptsseq['values'].split(','):
combo.append_text(i)
table.attach(HIGEntryLabel(_('Class:')),0,1,0,1)
table.attach(HIGEntryLabel(tcptsseq['class']),1,2,0,1)
table.attach(HIGEntryLabel(_('Class:')), 0, 1, 0, 1)
table.attach(HIGEntryLabel(tcptsseq['class']), 1, 2, 0, 1)
table.attach(HIGEntryLabel(_('Values:')),0,1,1,2)
table.attach(combo,1,2,1,2)
table.attach(HIGEntryLabel(_('Values:')), 0, 1, 1, 2)
table.attach(combo, 1, 2, 1, 2)
self.tcpts_expander.add(hbox)
self._pack_noexpand_nofill(self.tcpts_expander)
@@ -515,8 +557,8 @@ class HostDetails(HIGVBox):
self.comment_scrolled = gtk.ScrolledWindow()
self.comment_scrolled.set_border_width(5)
self.comment_scrolled.set_policy(gtk.POLICY_AUTOMATIC,\
gtk.POLICY_AUTOMATIC)
self.comment_scrolled.set_policy(
gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self.comment_txt_vw = gtk.TextView()
self.comment_txt_vw.set_wrap_mode(gtk.WRAP_WORD)

View File

@@ -127,16 +127,19 @@ from zenmapGUI.higwidgets.higboxes import HIGVBox
from zenmapGUI.Icons import get_os_icon
import zenmapCore.I18N
def treemodel_get_addrs_for_sort(model, iter):
host = model.get_value(iter, 0)
return host.get_addrs_for_sort()
# Used to sort hosts by address.
def cmp_treemodel_addr(model, iter_a, iter_b):
addrs_a = treemodel_get_addrs_for_sort(model, iter_a)
addrs_b = treemodel_get_addrs_for_sort(model, iter_b)
return cmp(addrs_a, addrs_b)
class ScanHostsView(HIGVBox, object):
HOST_MODE, SERVICE_MODE = range(2)
@@ -272,8 +275,8 @@ class ScanHostsView(HIGVBox, object):
self.host_column.pack_start(self.host_cell, True)
self.pic_column.set_min_width(35)
self.pic_column.set_attributes(self.os_cell, stock_id = 1)
self.host_column.set_attributes(self.host_cell, text = 2)
self.pic_column.set_attributes(self.os_cell, stock_id=1)
self.host_column.set_attributes(self.host_cell, text=2)
def mass_update(self, hosts):
"""Update the internal ListStores to reflect the hosts and services

View File

@@ -145,7 +145,8 @@ from zenmapGUI.ScanScanListPage import ScanScanListPage
from zenmapGUI.ScansListStore import ScansListStore
from zenmapGUI.TopologyPage import TopologyPage
from zenmapCore.NetworkInventory import NetworkInventory, FilteredNetworkInventory
from zenmapCore.NetworkInventory import NetworkInventory,\
FilteredNetworkInventory
from zenmapCore.NmapCommand import NmapCommand
from zenmapCore.UmitConf import CommandProfile, ProfileNotFound, is_maemo
from zenmapCore.NmapParser import NmapParser
@@ -157,6 +158,7 @@ import zenmapCore.I18N
# How often the live output view refreshes, in milliseconds.
NMAP_OUTPUT_REFRESH_INTERVAL = 1000
class ScanInterface(HIGVBox):
"""ScanInterface contains the scan toolbar and the scan results. Each
ScanInterface represents a single NetworkInventory as well as a set of
@@ -204,20 +206,26 @@ class ScanInterface(HIGVBox):
scan_interface=self)
self.host_view_selection = self.scan_result.get_host_selection()
self.service_view_selection = self.scan_result.get_service_selection()
self.host_view_selection.connect('changed', self.host_selection_changed)
self.service_view_selection.connect('changed', self.service_selection_changed)
self.host_view_selection.connect(
'changed', self.host_selection_changed)
self.service_view_selection.connect(
'changed', self.service_selection_changed)
host_page = self.scan_result.scan_result_notebook.open_ports.host
host_page.host_view.get_selection().connect('changed', self.service_host_selection_changed)
self.host_view_selection.connect('changed', self.host_selection_changed)
host_page.host_view.get_selection().connect(
'changed', self.service_host_selection_changed)
self.host_view_selection.connect(
'changed', self.host_selection_changed)
self.scan_result.scan_result_notebook.nmap_output.connect("changed", self._displayed_scan_change_cb)
self.scan_result.scan_result_notebook.scans_list.remove_button.connect("clicked", self._remove_scan_cb)
self.scan_result.scan_result_notebook.nmap_output.connect(
"changed", self._displayed_scan_change_cb)
self.scan_result.scan_result_notebook.scans_list.remove_button.connect(
"clicked", self._remove_scan_cb)
# The hosts dict maps hostnames (as returned by HostInfo.get_hostname)
# to HostInfo objects.
self.hosts = {}
# The services dict maps service names ("http") to lists of dicts of the
# form
# The services dict maps service names ("http") to lists of dicts of
# the form
# {'host': <HostInfo object>, 'hostname': u'example.com',
# 'port_state': u'open', 'portid': u'22', 'protocol': u'tcp',
# 'service_conf': u'10', 'service_extrainfo': u'protocol 2.0',
@@ -236,7 +244,8 @@ class ScanInterface(HIGVBox):
self._pack_noexpand_nofill(self.top_box)
self._pack_expand_fill(self.scan_result)
self.scan_result.scan_result_notebook.scans_list.cancel_button.connect("clicked", self._cancel_scans_list_cb)
self.scan_result.scan_result_notebook.scans_list.cancel_button.connect(
"clicked", self._cancel_scans_list_cb)
self.update_cancel_button()
# Create the filter GUI
@@ -271,16 +280,18 @@ class ScanInterface(HIGVBox):
# Restart the timer to start the filter.
if self.filter_timeout_id:
gobject.source_remove(self.filter_timeout_id)
self.filter_timeout_id = gobject.timeout_add(self.FILTER_DELAY, self.filter_hosts, filter_bar.get_filter_string())
self.filter_timeout_id = gobject.timeout_add(
self.FILTER_DELAY, self.filter_hosts,
filter_bar.get_filter_string())
def filter_hosts(self, filter_string):
start = time.clock()
self.inventory.apply_filter(filter_string)
filter_time = time.clock() - start;
filter_time = time.clock() - start
# Update the gui
start = time.clock()
self.update_ui()
gui_time = time.clock() - start;
gui_time = time.clock() - start
if filter_time + gui_time > 0.0:
log.debug("apply_filter %g ms update_ui %g ms (%.0f%% filter)" %
@@ -302,8 +313,8 @@ class ScanInterface(HIGVBox):
return len(self.jobs)
def select_default_profile(self):
"""Select a "default" profile. Currently this is defined to be the first
profile."""
"""Select a "default" profile. Currently this is defined to be the
first profile."""
if len(self.toolbar.profile_entry.get_model()) > 0:
self.toolbar.profile_entry.set_active(0)
@@ -314,21 +325,22 @@ class ScanInterface(HIGVBox):
def __create_toolbar(self):
self.toolbar = ScanToolbar()
self.target_entry_changed_handler = \
self.toolbar.target_entry.connect('changed', self._target_entry_changed)
self.target_entry_changed_handler = self.toolbar.target_entry.connect(
'changed', self._target_entry_changed)
self.profile_entry_changed_handler = \
self.toolbar.profile_entry.connect('changed', self._profile_entry_changed)
self.toolbar.profile_entry.connect(
'changed', self._profile_entry_changed)
self.toolbar.scan_button.connect('clicked', self.start_scan_cb)
self.toolbar.cancel_button.connect('clicked', self._cancel_scan_cb)
def __create_command_toolbar(self):
self.command_toolbar = ScanCommandToolbar()
self.command_toolbar.command_entry.connect('activate',
lambda x: self.toolbar.scan_button.clicked())
self.command_toolbar.command_entry.connect(
'activate', lambda x: self.toolbar.scan_button.clicked())
self.command_entry_changed_handler = \
self.command_toolbar.command_entry.connect('changed', self._command_entry_changed)
self.command_toolbar.command_entry.connect(
'changed', self._command_entry_changed)
def _command_entry_changed(self, editable):
ops = NmapOptions()
@@ -378,23 +390,29 @@ class ScanInterface(HIGVBox):
def set_command_quiet(self, command_string):
"""Set the command used by this scan interface, ignoring any further
"changed" signals."""
self.command_toolbar.command_entry.handler_block(self.command_entry_changed_handler)
self.command_toolbar.command_entry.handler_block(
self.command_entry_changed_handler)
self.command_toolbar.set_command(command_string)
self.command_toolbar.command_entry.handler_unblock(self.command_entry_changed_handler)
self.command_toolbar.command_entry.handler_unblock(
self.command_entry_changed_handler)
def set_target_quiet(self, target_string):
"""Set the target string used by this scan interface, ignoring any
further "changed" signals."""
self.toolbar.target_entry.handler_block(self.target_entry_changed_handler)
self.toolbar.target_entry.handler_block(
self.target_entry_changed_handler)
self.toolbar.set_selected_target(target_string)
self.toolbar.target_entry.handler_unblock(self.target_entry_changed_handler)
self.toolbar.target_entry.handler_unblock(
self.target_entry_changed_handler)
def set_profile_name_quiet(self, profile_name):
"""Set the profile name used by this scan interface, ignoring any
further "changed" signals."""
self.toolbar.profile_entry.handler_block(self.profile_entry_changed_handler)
self.toolbar.profile_entry.handler_block(
self.profile_entry_changed_handler)
self.toolbar.set_selected_profile(profile_name)
self.toolbar.profile_entry.handler_unblock(self.profile_entry_changed_handler)
self.toolbar.profile_entry.handler_unblock(
self.profile_entry_changed_handler)
def start_scan_cb(self, widget=None):
target = self.toolbar.selected_target
@@ -412,14 +430,17 @@ class ScanInterface(HIGVBox):
except IOError, e:
# We failed to save target_list.txt; treat it as read-only.
# Probably it's owned by root and this is a normal user.
log.debug(">>> Error saving %s: %s" % (Path.target_list, str(e)))
log.debug(">>> Error saving %s: %s" % (
Path.target_list, str(e)))
if command == '':
warn_dialog = HIGAlertDialog(message_format=_("Empty Nmap Command"),
secondary_text=_("There is no command to \
execute. Maybe the selected/typed profile doesn't exist. Please, check the profile name \
or type the nmap command you would like to execute."),
type=gtk.MESSAGE_ERROR)
warn_dialog = HIGAlertDialog(
message_format=_("Empty Nmap Command"),
secondary_text=_("There is no command to execute. "
"Maybe the selected/typed profile doesn't exist. "
"Please check the profile name or type the nmap "
"command you would like to execute."),
type=gtk.MESSAGE_ERROR)
warn_dialog.run()
warn_dialog.destroy()
return
@@ -467,8 +488,8 @@ or type the nmap command you would like to execute."),
self.inventory.remove_scan(entry.parsed)
except ValueError:
pass
# Create TreeRowReferences because those persist while we change the
# model.
# Create TreeRowReferences because those persist while we change
# the model.
selected_refs.append(gtk.TreeRowReference(model, path))
# Delete the entries from the ScansListStore.
for ref in selected_refs:
@@ -500,7 +521,7 @@ or type the nmap command you would like to execute."),
self.jobs.remove(command)
self.update_cancel_button()
def execute_command(self, command, target = None, profile = None):
def execute_command(self, command, target=None, profile=None):
"""Run the given Nmap command. Add it to the list of running scans.
Schedule a timer to refresh the output and check the scan for
completion."""
@@ -515,21 +536,27 @@ or type the nmap command you would like to execute."),
# Handle ENOENT specially.
if e.errno == errno.ENOENT:
# nmap_command_path comes from zenmapCore.NmapCommand.
text += "\n\n" + _("This means that the nmap executable was not found in your system PATH, which is") + "\n\n" + os.getenv("PATH", _("<undefined>"))
text += "\n\n%s\n\n%s" % (
_("This means that the nmap executable was "
"not found in your system PATH, which is"),
os.getenv("PATH", _("<undefined>"))
)
path_env = os.getenv("PATH")
if path_env is None:
default_paths = []
else:
default_paths = path_env.split(os.pathsep)
extra_paths = get_extra_executable_search_paths()
extra_paths = [p for p in extra_paths if p not in default_paths]
extra_paths = [p for p in extra_paths if (
p not in default_paths)]
if len(extra_paths) > 0:
if len(extra_paths) == 1:
text += "\n\n" + _("plus the extra directory")
else:
text += "\n\n" + _("plus the extra directories")
text += "\n\n" + os.pathsep.join(extra_paths)
warn_dialog = HIGAlertDialog(message_format=_("Error executing command"),
warn_dialog = HIGAlertDialog(
message_format=_("Error executing command"),
secondary_text=text, type=gtk.MESSAGE_ERROR)
warn_dialog.run()
warn_dialog.destroy()
@@ -546,7 +573,8 @@ or type the nmap command you would like to execute."),
self.scan_result.refresh_nmap_output()
# Add a timeout function
self.verify_thread_timeout_id = gobject.timeout_add(NMAP_OUTPUT_REFRESH_INTERVAL, self.verify_execution)
self.verify_thread_timeout_id = gobject.timeout_add(
NMAP_OUTPUT_REFRESH_INTERVAL, self.verify_execution)
def verify_execution(self):
"""This is a callback that is called periodically to refresh the output
@@ -597,12 +625,12 @@ or type the nmap command you would like to execute."),
except:
st = None
if st is None or st.st_size > 0:
warn_dialog = HIGAlertDialog(message_format = _("Parse error"),
secondary_text = _(u"""\
There was an error while parsing the XML file generated from the scan:
%s\
""") % str(e), type = gtk.MESSAGE_ERROR)
warn_dialog = HIGAlertDialog(
message_format=_("Parse error"),
secondary_text=_(
"There was an error while parsing the XML file "
"generated from the scan:\n\n%s""") % str(e),
type=gtk.MESSAGE_ERROR)
warn_dialog.run()
warn_dialog.destroy()
else:
@@ -612,12 +640,12 @@ There was an error while parsing the XML file generated from the scan:
try:
self.inventory.add_scan(parsed)
except Exception, e:
warn_dialog = HIGAlertDialog(message_format = _("Cannot merge scan"),
secondary_text = _(u"""\
There was an error while merging the new scan's XML:
%s\
""") % str(e), type = gtk.MESSAGE_ERROR)
warn_dialog = HIGAlertDialog(
message_format=_("Cannot merge scan"),
secondary_text=_(
"There was an error while merging the new scan's "
"XML:\n\n%s") % str(e),
type=gtk.MESSAGE_ERROR)
warn_dialog.run()
warn_dialog.destroy()
parsed.set_xml_is_temp(command.xml_is_temp)
@@ -686,27 +714,29 @@ There was an error while merging the new scan's XML:
if name not in self.services.keys():
self.services[name] = []
hs = {"host":host, "hostname":hostname}
hs = {"host": host, "hostname": hostname}
hs.update(service)
self.services[name].append(hs)
self.hosts[hostname] = host
# If the host and service selection is empty or has become empty, select
# the first host if there is at least one.
if len(self.host_view_selection.get_selected_rows()[1]) == 0 \
and len(self.service_view_selection.get_selected_rows()[1]) == 0 \
and len(self.scan_result.scan_host_view.host_list) > 0:
self.host_view_selection.select_iter(self.scan_result.scan_host_view.host_list.get_iter_first())
# If the host and service selection is empty or has become empty,
# select the first host if there is at least one.
if (len(self.service_view_selection.get_selected_rows()[1]) == 0 and
len(self.host_view_selection.get_selected_rows()[1]) == 0 and
len(self.scan_result.scan_host_view.host_list) > 0):
self.host_view_selection.select_iter(
self.scan_result.scan_host_view.host_list.get_iter_first())
self.filter_bar.set_information_text(_("%d/%d hosts shown") %
(len(self.inventory.get_hosts_up()),
len(NetworkInventory.get_hosts_up(self.inventory))))
if self.scan_result.scan_host_view.mode == ScanHostsView.HOST_MODE:
mode = self.scan_result.scan_host_view.mode
if mode == ScanHostsView.HOST_MODE:
self.refresh_port_output()
elif self.scan_result.scan_host_view.mode == ScanHostsView.SERVICE_MODE:
elif mode == ScanHostsView.SERVICE_MODE:
self.refresh_host_output()
def refresh_port_output(self):
@@ -714,11 +744,12 @@ There was an error while merging the new scan's XML:
current host selection."""
self.scan_result.scan_result_notebook.port_mode()
model_host_list, selection = self.host_view_selection.get_selected_rows()
model_host_list, selection = \
self.host_view_selection.get_selected_rows()
host_objs = []
for i in selection:
hostname = model_host_list[i[0]][2]
if self.hosts.has_key(hostname):
if hostname in self.hosts:
host_objs.append(self.hosts[hostname])
if len(host_objs) == 1:
@@ -732,11 +763,12 @@ There was an error while merging the new scan's XML:
current service selection."""
self.scan_result.scan_result_notebook.host_mode()
model_service_list, selection = self.service_view_selection.get_selected_rows()
model_service_list, selection = \
self.service_view_selection.get_selected_rows()
serv_objs = []
for i in selection:
key = model_service_list[i[0]][0]
if self.services.has_key(key):
if key in self.services:
serv_objs.append(self.services[key])
# Each element of serv_objs is a list of port dicts.
@@ -745,7 +777,9 @@ There was an error while merging the new scan's XML:
else:
servs = []
for s in serv_objs:
servs.append({"service_name":s[0]["service_name"], "ports": s})
servs.append({
"service_name": s[0]["service_name"],
"ports": s})
self.set_multiple_service_host(servs)
def host_selection_changed(self, widget):
@@ -791,7 +825,8 @@ There was an error while merging the new scan's XML:
"""Sets the comment on a host from the contents of the comment text
entry."""
buff = widget.get_buffer()
host.comment = buff.get_text(buff.get_start_iter(), buff.get_end_iter())
host.comment = buff.get_text(
buff.get_start_iter(), buff.get_end_iter())
for scan in self.inventory.get_scans():
if host in scan.get_hosts():
scan.unsaved = True
@@ -803,8 +838,10 @@ There was an error while merging the new scan's XML:
pages = []
for host in hosts:
page = ScanHostDetailsPage(host)
page.host_details.comment_txt_vw.connect("insert-at-cursor", self._save_comment, host)
page.host_details.comment_txt_vw.connect("focus-out-event", self._save_comment, host)
page.host_details.comment_txt_vw.connect(
"insert-at-cursor", self._save_comment, host)
page.host_details.comment_txt_vw.connect(
"focus-out-event", self._save_comment, host)
pages.append(page)
return pages
@@ -833,9 +870,9 @@ There was an error while merging the new scan's XML:
host_page.thaw()
def set_multiple_host_port(self, host_list):
"""Change the "Ports / Hosts" tab to show the port output for all of the
hosts in host_list. When multiple hosts are selected, the port output
for each is contained in an expander."""
"""Change the "Ports / Hosts" tab to show the port output for all of
the hosts in host_list. When multiple hosts are selected, the port
output for each is contained in an expander."""
host_page = self.scan_result.scan_result_notebook.open_ports.host
host_page.switch_port_to_tree_store()
@@ -846,19 +883,22 @@ There was an error while merging the new scan's XML:
host_page.thaw()
def set_multiple_service_host(self, service_list):
"""Change the "Ports / Hosts" tab to show the hosts associated with each
of the services in service_list. Each element of service_list must be a
dict with the keys "service_name" and "ports". When multiple services
are selected, the hosts for each are contained in an expander."""
"""Change the "Ports / Hosts" tab to show the hosts associated with
each of the services in service_list. Each element of service_list must
be a dict with the keys "service_name" and "ports". When multiple
services are selected, the hosts for each are contained in an
expander."""
host_page = self.scan_result.scan_result_notebook.open_ports.host
host_page.switch_host_to_tree_store()
host_page.freeze()
host_page.clear_host_tree()
for service in service_list:
host_page.add_to_host_tree(service["service_name"], service["ports"])
host_page.add_to_host_tree(
service["service_name"], service["ports"])
host_page.thaw()
class ScanResult(gtk.HPaned):
"""This is the pane that has the "Host"/"Service" column (ScanHostsView) on
the left and the "Nmap Output"/"Ports / Hosts"/etc. (ScanResultNotebook) on
@@ -915,7 +955,8 @@ class ScanResultNotebook(HIGNotebook):
self.__create_widgets(inventory, scans_store)
self.scans_list.scans_list.connect("row-activated", self._scan_row_activated)
self.scans_list.scans_list.connect(
"row-activated", self._scan_row_activated)
self.append_page(self.nmap_output_page, gtk.Label(_('Nmap Output')))
self.append_page(self.open_ports_page, gtk.Label(_('Ports / Hosts')))

View File

@@ -134,6 +134,7 @@ from zenmapCore.Paths import Path
from zenmapCore.UmitLogging import log
import zenmapCore.I18N
def scan_entry_data_func(widget, cell_renderer, model, iter):
"""Set the properties of a cell renderer for a scan entry."""
cell_renderer.set_property("ellipsize", pango.ELLIPSIZE_END)
@@ -150,12 +151,15 @@ def scan_entry_data_func(widget, cell_renderer, model, iter):
cell_renderer.set_property("strikethrough", True)
cell_renderer.set_property("text", entry.get_command_string())
class Throbber(gtk.Image):
"""This is a little progress indicator that animates while a scan is
running."""
try:
still = gtk.gdk.pixbuf_new_from_file(os.path.join(Path.pixmaps_dir, "throbber.png"))
anim = gtk.gdk.PixbufAnimation(os.path.join(Path.pixmaps_dir, "throbber.gif"))
still = gtk.gdk.pixbuf_new_from_file(
os.path.join(Path.pixmaps_dir, "throbber.png"))
anim = gtk.gdk.PixbufAnimation(
os.path.join(Path.pixmaps_dir, "throbber.gif"))
except Exception, e:
log.debug("Error loading throbber images: %s." % str(e))
still = None
@@ -177,6 +181,7 @@ class Throbber(gtk.Image):
self.set_from_pixbuf(self.still)
self.animating = False
class ScanNmapOutputPage(HIGVBox):
"""This is the "Nmap Output" scan results tab. It holds a text view of Nmap
output. The constructor takes a ScansListStore, the contents of which are
@@ -223,8 +228,8 @@ class ScanNmapOutputPage(HIGVBox):
self._update()
def set_active_iter(self, i):
"""Set the active entry to an interator into the ScansListStore referred
to by this object."""
"""Set the active entry to an interator into the ScansListStore
referred to by this object."""
self.scans_list.set_active_iter(i)
def get_active_entry(self):
@@ -287,9 +292,11 @@ class ScanNmapOutputPage(HIGVBox):
if self._details_windows.get(entry) is None:
window = gtk.Window()
window.add(ScanRunDetailsPage(entry.parsed))
def close_details(details, event, entry):
details.destroy()
del self._details_windows[entry]
window.connect("delete-event", close_details, entry)
window.show_all()
self._details_windows[entry] = window

View File

@@ -128,12 +128,14 @@ from zenmapGUI.higwidgets.higtables import HIGTable
from zenmapCore.UmitLogging import log
import zenmapCore.I18N
def findout_service_icon(port_info):
if port_info["port_state"] in ["open", "open|filtered"]:
return gtk.STOCK_YES
else:
return gtk.STOCK_NO
def get_version_string(d):
"""Get a human-readable version string from the dict d. The keys used in d
are "service_product", "service_version", and "service_extrainfo" (all are
@@ -148,38 +150,45 @@ def get_version_string(d):
result.append("(" + d["service_extrainfo"] + ")")
return " ".join(result)
def get_addrs(host):
if host is None:
return None
return host.get_addrs_for_sort()
def cmp_addrs(host_a, host_b):
return cmp(get_addrs(host_a), get_addrs(host_b))
def cmp_port_list_addr(model, iter_a, iter_b):
host_a = model.get_value(iter_a, 0)
host_b = model.get_value(iter_b, 0)
return cmp_addrs(host_a, host_b)
def cmp_port_tree_addr(model, iter_a, iter_b):
host_a = model.get_value(iter_a, 0)
host_b = model.get_value(iter_b, 0)
return cmp_addrs(host_a, host_b)
def cmp_host_list_addr(model, iter_a, iter_b):
host_a = model.get_value(iter_a, 2)
host_b = model.get_value(iter_b, 2)
return cmp_addrs(host_a, host_b)
def cmp_host_tree_addr(model, iter_a, iter_b):
host_a = model.get_value(iter_a, 2)
host_b = model.get_value(iter_b, 2)
return cmp_addrs(host_a, host_b)
class ScanOpenPortsPage(gtk.ScrolledWindow):
def __init__(self):
gtk.ScrolledWindow.__init__(self)
self.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self.__create_widgets()
@@ -188,6 +197,7 @@ class ScanOpenPortsPage(gtk.ScrolledWindow):
def __create_widgets(self):
self.host = HostOpenPorts()
class HostOpenPorts(HIGVBox):
def __init__(self):
HIGVBox.__init__(self)
@@ -203,8 +213,10 @@ class HostOpenPorts(HIGVBox):
# host hostname icon port protocol state service version
# The hostname column is shown only when more than one host is selected
# (hence port_tree not port_list is used).
self.port_list = gtk.ListStore(object, str, str, int, str, str, str, str)
self.port_tree = gtk.TreeStore(object, str, str, int, str, str, str, str)
self.port_list = gtk.ListStore(
object, str, str, int, str, str, str, str)
self.port_tree = gtk.TreeStore(
object, str, str, int, str, str, str, str)
self.port_list.set_sort_func(1000, cmp_port_list_addr)
self.port_list.set_sort_column_id(1000, gtk.SORT_ASCENDING)
@@ -229,8 +241,10 @@ class HostOpenPorts(HIGVBox):
# service icon host hostname port protocol state version
# service is shown only when more than one service is selected (hence
# host_tree not host_list is used).
self.host_list = gtk.ListStore(str, str, object, str, int, str, str, str)
self.host_tree = gtk.TreeStore(str, str, object, str, int, str, str, str)
self.host_list = gtk.ListStore(
str, str, object, str, int, str, str, str)
self.host_tree = gtk.TreeStore(
str, str, object, str, int, str, str, str)
self.host_list.set_sort_func(1000, cmp_host_list_addr)
self.host_list.set_sort_column_id(1000, gtk.SORT_ASCENDING)
@@ -285,7 +299,8 @@ class HostOpenPorts(HIGVBox):
self.host_columns['state'].pack_start(self.cell_port, True)
self.host_columns['service'].set_attributes(self.cell_port, text=0)
self.host_columns['icon'].set_attributes(self.cell_host_icon, stock_id=1)
self.host_columns['icon'].set_attributes(
self.cell_host_icon, stock_id=1)
self.host_columns['hostname'].set_attributes(self.cell_port, text=3)
self.host_columns['port_number'].set_attributes(self.cell_port, text=4)
self.host_columns['protocol'].set_attributes(self.cell_port, text=5)
@@ -294,7 +309,8 @@ class HostOpenPorts(HIGVBox):
self.host_columns['service'].set_visible(False)
self.scroll_ports_hosts.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self.scroll_ports_hosts.set_policy(
gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
def _set_port_list(self):
self.port_view.set_enable_search(True)
@@ -315,7 +331,6 @@ class HostOpenPorts(HIGVBox):
self.port_columns[k].set_reorderable(True)
self.port_columns[k].set_resizable(True)
self.port_columns['icon'].set_min_width(35)
self.port_columns['hostname'].set_sort_column_id(1000)
@@ -368,10 +383,14 @@ class HostOpenPorts(HIGVBox):
def freeze(self):
"""Freeze notifications and sorting to make adding lots of elements to
the model faster."""
self.frozen_host_list_sort_column_id = self.host_list.get_sort_column_id()
self.frozen_host_tree_sort_column_id = self.host_tree.get_sort_column_id()
self.frozen_port_list_sort_column_id = self.port_list.get_sort_column_id()
self.frozen_port_tree_sort_column_id = self.port_tree.get_sort_column_id()
self.frozen_host_list_sort_column_id = \
self.host_list.get_sort_column_id()
self.frozen_host_tree_sort_column_id = \
self.host_tree.get_sort_column_id()
self.frozen_port_list_sort_column_id = \
self.port_list.get_sort_column_id()
self.frozen_port_tree_sort_column_id = \
self.port_tree.get_sort_column_id()
self.host_list.set_default_sort_func(lambda *args: -1)
self.host_tree.set_default_sort_func(lambda *args: -1)
self.port_list.set_default_sort_func(lambda *args: -1)
@@ -387,13 +406,17 @@ class HostOpenPorts(HIGVBox):
"""Restore notifications and sorting (after making changes to the
model)."""
if self.frozen_host_list_sort_column_id != (None, None):
self.host_list.set_sort_column_id(*self.frozen_host_list_sort_column_id)
self.host_list.set_sort_column_id(
*self.frozen_host_list_sort_column_id)
if self.frozen_host_tree_sort_column_id != (None, None):
self.host_tree.set_sort_column_id(*self.frozen_host_tree_sort_column_id)
self.host_tree.set_sort_column_id(
*self.frozen_host_tree_sort_column_id)
if self.frozen_port_list_sort_column_id != (None, None):
self.port_list.set_sort_column_id(*self.frozen_port_list_sort_column_id)
self.port_list.set_sort_column_id(
*self.frozen_port_list_sort_column_id)
if self.frozen_port_tree_sort_column_id != (None, None):
self.port_tree.set_sort_column_id(*self.frozen_port_tree_sort_column_id)
self.port_tree.set_sort_column_id(
*self.frozen_port_tree_sort_column_id)
self.host_view.set_model(self.frozen_host_view_model)
self.port_view.set_model(self.frozen_port_view_model)
self.host_view.thaw_child_notify()
@@ -414,7 +437,8 @@ class HostOpenPorts(HIGVBox):
self.host_list.append(entry)
def add_to_port_tree(self, host):
parent = self.port_tree.append(None, [host, host.get_hostname(), None, 0,'','','',''])
parent = self.port_tree.append(
None, [host, host.get_hostname(), None, 0, '', '', '', ''])
for p in host.get_ports():
self.port_tree.append(parent,
[None, '', findout_service_icon(p), int(p.get('portid', "0")),
@@ -422,12 +446,21 @@ class HostOpenPorts(HIGVBox):
p.get('service_name', _("Unknown")), get_version_string(p)])
def add_to_host_tree(self, service_name, ports):
parent = self.host_tree.append(None, [service_name, '', None, '', 0, '', '', ''])
parent = self.host_tree.append(
None, [service_name, '', None, '', 0, '', '', ''])
for p in ports:
self.host_tree.append(parent,
['', findout_service_icon(p), p["host"], p["host"].get_hostname(),
int(p.get('portid', "0")), p.get('protocol', ""),
p.get('port_state', _("Unknown")), get_version_string(p)])
[
'',
findout_service_icon(p),
p["host"],
p["host"].get_hostname(),
int(p.get('portid', "0")),
p.get('protocol', ""),
p.get('port_state', _("Unknown")),
get_version_string(p)
]
)
def switch_port_to_list_store(self):
if self.port_view.get_model() != self.port_list:

View File

@@ -121,12 +121,14 @@
# ***************************************************************************/
import gtk
from zenmapGUI.higwidgets.higboxes import HIGVBox, HIGHBox, hig_box_space_holder
from zenmapGUI.higwidgets.higboxes import HIGVBox, HIGHBox,\
hig_box_space_holder
from zenmapGUI.higwidgets.higtables import HIGTable
from zenmapGUI.higwidgets.higlabels import HIGEntryLabel
import zenmapCore.I18N
class ScanRunDetailsPage(HIGVBox):
def __init__(self, scan):
HIGVBox.__init__(self)
@@ -146,7 +148,8 @@ class ScanRunDetailsPage(HIGVBox):
self.debug_label = HIGEntryLabel(_('Debug level:'))
self.info_debug_label = HIGEntryLabel(na)
self.command_expander = gtk.Expander("<b>"+_("Command Info")+"</b>")
self.command_expander = gtk.Expander(
"<b>" + _("Command Info") + "</b>")
self.command_expander.set_use_markup(True)
self.command_table = HIGTable()
@@ -158,17 +161,17 @@ class ScanRunDetailsPage(HIGVBox):
self.command_hbox._pack_noexpand_nofill(hig_box_space_holder())
self.command_hbox._pack_noexpand_nofill(self.command_table)
self.command_table.attach(self.command_label,0,1,0,1)
self.command_table.attach(self.info_command_label,1,2,0,1)
self.command_table.attach(self.command_label, 0, 1, 0, 1)
self.command_table.attach(self.info_command_label, 1, 2, 0, 1)
self.command_table.attach(self.nmap_version_label,0,1,1,2)
self.command_table.attach(self.info_nmap_version_label,1,2,1,2)
self.command_table.attach(self.nmap_version_label, 0, 1, 1, 2)
self.command_table.attach(self.info_nmap_version_label, 1, 2, 1, 2)
self.command_table.attach(self.verbose_label,0,1,2,3)
self.command_table.attach(self.info_verbose_label,1,2,2,3)
self.command_table.attach(self.verbose_label, 0, 1, 2, 3)
self.command_table.attach(self.info_verbose_label, 1, 2, 2, 3)
self.command_table.attach(self.debug_label,0,1,3,4)
self.command_table.attach(self.info_debug_label,1,2,3,4)
self.command_table.attach(self.debug_label, 0, 1, 3, 4)
self.command_table.attach(self.info_debug_label, 1, 2, 3, 4)
self.command_expander.add(self.command_hbox)
self._pack_noexpand_nofill(self.command_expander)
@@ -199,7 +202,8 @@ class ScanRunDetailsPage(HIGVBox):
self.closed_label = HIGEntryLabel(_('Closed ports:'))
self.info_closed_label = HIGEntryLabel(na)
self.general_expander = gtk.Expander("<b>"+_("General Info")+"</b>")
self.general_expander = gtk.Expander(
"<b>" + _("General Info") + "</b>")
self.general_expander.set_use_markup(True)
self.general_table = HIGTable()
@@ -211,29 +215,29 @@ class ScanRunDetailsPage(HIGVBox):
self.general_hbox._pack_noexpand_nofill(hig_box_space_holder())
self.general_hbox._pack_noexpand_nofill(self.general_table)
self.general_table.attach(self.start_label,0,1,0,1)
self.general_table.attach(self.info_start_label,1,2,0,1)
self.general_table.attach(self.start_label, 0, 1, 0, 1)
self.general_table.attach(self.info_start_label, 1, 2, 0, 1)
self.general_table.attach(self.finished_label,0,1,1,2)
self.general_table.attach(self.info_finished_label,1,2,1,2)
self.general_table.attach(self.finished_label, 0, 1, 1, 2)
self.general_table.attach(self.info_finished_label, 1, 2, 1, 2)
self.general_table.attach(self.host_up_label,0,1,2,3)
self.general_table.attach(self.info_hosts_up_label,1,2,2,3)
self.general_table.attach(self.host_up_label, 0, 1, 2, 3)
self.general_table.attach(self.info_hosts_up_label, 1, 2, 2, 3)
self.general_table.attach(self.host_down_label,0,1,3,4)
self.general_table.attach(self.info_hosts_down_label,1,2,3,4)
self.general_table.attach(self.host_down_label, 0, 1, 3, 4)
self.general_table.attach(self.info_hosts_down_label, 1, 2, 3, 4)
self.general_table.attach(self.host_scanned_label,0,1,4,5)
self.general_table.attach(self.info_hosts_scanned_label,1,2,4,5)
self.general_table.attach(self.host_scanned_label, 0, 1, 4, 5)
self.general_table.attach(self.info_hosts_scanned_label, 1, 2, 4, 5)
self.general_table.attach(self.open_label,0,1,5,6)
self.general_table.attach(self.info_open_label,1,2,5,6)
self.general_table.attach(self.open_label, 0, 1, 5, 6)
self.general_table.attach(self.info_open_label, 1, 2, 5, 6)
self.general_table.attach(self.filtered_label,0,1,6,7)
self.general_table.attach(self.info_filtered_label,1,2,6,7)
self.general_table.attach(self.filtered_label, 0, 1, 6, 7)
self.general_table.attach(self.info_filtered_label, 1, 2, 6, 7)
self.general_table.attach(self.closed_label,0,1,7,8)
self.general_table.attach(self.info_closed_label,1,2,7,8)
self.general_table.attach(self.closed_label, 0, 1, 7, 8)
self.general_table.attach(self.info_closed_label, 1, 2, 7, 8)
self.general_expander.add(self.general_hbox)
self._pack_noexpand_nofill(self.general_expander)
@@ -260,7 +264,8 @@ class ScanRunDetailsPage(HIGVBox):
self.info_closed_label.set_text(str(scan.get_closed_ports()))
for scaninfo in scan.get_scaninfo():
exp = gtk.Expander('<b>%s - %s</b>' % (_('Scan Info'), scaninfo['type'].capitalize()))
exp = gtk.Expander('<b>%s - %s</b>' % (
_('Scan Info'), scaninfo['type'].capitalize()))
exp.set_use_markup(True)
display = self.make_scaninfo_display(scaninfo)
@@ -277,17 +282,18 @@ class ScanRunDetailsPage(HIGVBox):
table.set_row_spacings(6)
table.set_col_spacings(6)
table.attach(HIGEntryLabel(_('Scan type:')),0,1,0,1)
table.attach(HIGEntryLabel(scaninfo['type']),1,2,0,1)
table.attach(HIGEntryLabel(_('Scan type:')), 0, 1, 0, 1)
table.attach(HIGEntryLabel(scaninfo['type']), 1, 2, 0, 1)
table.attach(HIGEntryLabel(_('Protocol:')),0,1,1,2)
table.attach(HIGEntryLabel(scaninfo['protocol']),1,2,1,2)
table.attach(HIGEntryLabel(_('Protocol:')), 0, 1, 1, 2)
table.attach(HIGEntryLabel(scaninfo['protocol']), 1, 2, 1, 2)
table.attach(HIGEntryLabel(_('# scanned ports:')),0,1,2,3)
table.attach(HIGEntryLabel(scaninfo['numservices']),1,2,2,3)
table.attach(HIGEntryLabel(_('# scanned ports:')), 0, 1, 2, 3)
table.attach(HIGEntryLabel(scaninfo['numservices']), 1, 2, 2, 3)
table.attach(HIGEntryLabel(_('Services:')),0,1,3,4)
table.attach(self.make_services_display(scaninfo['services']),1,2,3,4)
table.attach(HIGEntryLabel(_('Services:')), 0, 1, 3, 4)
table.attach(
self.make_services_display(scaninfo['services']), 1, 2, 3, 4)
hbox._pack_noexpand_nofill(hig_box_space_holder())
hbox._pack_noexpand_nofill(table)

View File

@@ -128,6 +128,7 @@ from zenmapGUI.higwidgets.higbuttons import HIGButton
from zenmapGUI.higwidgets.higscrollers import HIGScrolledWindow
import zenmapCore.I18N
def status_data_func(widget, cell_renderer, model, iter):
entry = model.get_value(iter, 0)
if entry.running:
@@ -143,14 +144,17 @@ def status_data_func(widget, cell_renderer, model, iter):
status = _("Canceled")
cell_renderer.set_property("text", status)
def command_data_func(widget, cell_renderer, model, iter):
entry = model.get_value(iter, 0)
cell_renderer.set_property("ellipsize", pango.ELLIPSIZE_END)
cell_renderer.set_property("text", entry.get_command_string())
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."""
"""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)
@@ -159,7 +163,8 @@ class ScanScanListPage(HIGVBox):
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)
self.scans_list.get_selection().connect(
"changed", self._selection_changed)
status_col = gtk.TreeViewColumn(_("Status"))
cell = gtk.CellRendererText()
@@ -193,9 +198,9 @@ class ScanScanListPage(HIGVBox):
self.cancel_button = HIGButton(_("Cancel Scan"), gtk.STOCK_CANCEL)
buttonbox.pack_start(self.cancel_button, False)
hbox.pack_start(buttonbox, padding = 4)
hbox.pack_start(buttonbox, padding=4)
self.pack_start(hbox, False, padding = 4)
self.pack_start(hbox, False, padding=4)
self._update()
@@ -206,13 +211,13 @@ class ScanScanListPage(HIGVBox):
self._update()
def _update(self):
# Make the Cancel button sensitive or not depending on whether a running
# scan is selected.
# 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.
# this is possible, but we received many crash reports that
# indicate it is.
model, selection = None, []
else:
model, selection = tree_selection.get_selected_rows()

View File

@@ -133,7 +133,8 @@ from zenmapGUI.TargetCombo import TargetCombo
class ScanCommandToolbar(HIGHBox):
"""This class builds the toolbar devoted to Command entry. It allows you to retrieve and edit the current command entered."""
"""This class builds the toolbar devoted to Command entry. It allows you to
retrieve and edit the current command entered."""
def __init__(self):
"""Initialize command toolbar"""
HIGHBox.__init__(self)
@@ -249,6 +250,6 @@ if __name__ == "__main__":
box.pack_start(stool)
box.pack_start(sctool)
w.connect("delete-event", lambda x,y: gtk.main_quit())
w.connect("delete-event", lambda x, y: gtk.main_quit())
w.show_all()
gtk.main()

View File

@@ -122,6 +122,7 @@
import gtk
class ScansListStoreEntry(object):
"""This class is an abstraction for running and completed scans, which are
otherwise represented by very different classes."""
@@ -134,11 +135,11 @@ class ScansListStoreEntry(object):
self.command = None
self.parsed = None
def set_running(self, command = None):
def set_running(self, command=None):
self.state = self.RUNNING
self.command = command
def set_finished(self, parsed = None):
def set_finished(self, parsed=None):
self.state = self.FINISHED
self.parsed = parsed
@@ -161,6 +162,7 @@ class ScansListStoreEntry(object):
failed = property(lambda self: self.state == self.FAILED)
canceled = property(lambda self: self.state == self.CANCELED)
class ScansListStore(gtk.ListStore):
"""This is a specialization of a gtk.ListStore that holds running,
completed, and failed scans."""

View File

@@ -129,7 +129,8 @@ import re
import xml.sax
from zenmapGUI.higwidgets.higwindows import HIGWindow
from zenmapGUI.higwidgets.higboxes import HIGVBox, HIGHBox, HIGSpacer, hig_box_space_holder
from zenmapGUI.higwidgets.higboxes import HIGVBox, HIGHBox, HIGSpacer,\
hig_box_space_holder
from zenmapGUI.higwidgets.higlabels import HIGSectionLabel, HIGEntryLabel
from zenmapGUI.higwidgets.higscrollers import HIGScrolledWindow
from zenmapGUI.higwidgets.higtextviewers import HIGTextView
@@ -149,11 +150,12 @@ from zenmapCore.Name import APP_NAME
paths_config = PathsConfig()
def text_buffer_insert_nsedoc(buf, nsedoc):
"""Inserts NSEDoc at the end of the buffer, with markup turned into proper
tags."""
if not buf.tag_table.lookup("NSEDOC_CODE_TAG"):
buf.create_tag("NSEDOC_CODE_TAG", font = "Monospace")
buf.create_tag("NSEDOC_CODE_TAG", font="Monospace")
for event in zenmapCore.NSEDocParser.nsedoc_parse(nsedoc):
if event.type == "paragraph_start":
buf.insert(buf.get_end_iter(), "\n")
@@ -164,13 +166,15 @@ def text_buffer_insert_nsedoc(buf, nsedoc):
elif event.type == "list_end":
pass
elif event.type == "list_item_start":
buf.insert(buf.get_end_iter(), u"\u2022\u00a0") # bullet nbsp
buf.insert(buf.get_end_iter(), u"\u2022\u00a0") # bullet nbsp
elif event.type == "list_item_end":
buf.insert(buf.get_end_iter(), "\n")
elif event.type == "text":
buf.insert(buf.get_end_iter(), event.text)
elif event.type == "code":
buf.insert_with_tags_by_name(buf.get_end_iter(), event.text, "NSEDOC_CODE_TAG")
buf.insert_with_tags_by_name(
buf.get_end_iter(), event.text, "NSEDOC_CODE_TAG")
class ScriptHelpXMLContentHandler (xml.sax.handler.ContentHandler):
"""A very simple parser for --script-help XML output. This could extract
@@ -183,11 +187,13 @@ class ScriptHelpXMLContentHandler (xml.sax.handler.ContentHandler):
def startElement(self, name, attrs):
if name == u"directory":
if not attrs.has_key(u"name"):
raise ValueError(u"\"directory\" element did not have \"name\" attribute")
if u"name" not in attrs:
raise ValueError(
u'"directory" element did not have "name" attribute')
dirname = attrs[u"name"]
if not attrs.has_key(u"path"):
raise ValueError(u"\"directory\" element did not have \"path\" attribute")
if u"path" not in attrs:
raise ValueError(
u'"directory" element did not have "path" attribute')
path = attrs[u"path"]
if dirname == u"scripts":
self.scripts_dir = path
@@ -197,8 +203,9 @@ class ScriptHelpXMLContentHandler (xml.sax.handler.ContentHandler):
# Ignore.
pass
elif name == u"script":
if not attrs.has_key(u"filename"):
raise ValueError(u"\"script\" element did not have \"filename\" attribute")
if u"filename" not in attrs:
raise ValueError(
u'"script" element did not have "filename" attribute')
self.script_filenames.append(attrs[u"filename"])
@staticmethod
@@ -209,6 +216,7 @@ class ScriptHelpXMLContentHandler (xml.sax.handler.ContentHandler):
parser.parse(f)
return handler
class ScriptInterface:
# Timeout, in milliseconds, after the user stops typing and we update the
# interface from --script.
@@ -216,9 +224,9 @@ class ScriptInterface:
# 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 # to show profile editor that it is a script tab
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
@@ -240,16 +248,16 @@ class ScriptInterface:
# 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
# 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 = 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()
@@ -269,8 +277,8 @@ There was an error getting the list of scripts from Nmap. Try upgrading Nmap.\
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."""
"--script-help=<rules> -oX -", and set it up to call the given callback
when finished."""
ops = NmapOptions()
ops.executable = paths_config.nmap_command_path
@@ -279,11 +287,12 @@ There was an error getting the list of scripts from Nmap. Try upgrading Nmap.\
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-")
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)
nmap_process.run_scan(stderr=stderr)
except Exception, e:
callback(False, None)
stderr.close()
@@ -292,14 +301,17 @@ There was an error getting the list of scripts from Nmap. Try upgrading Nmap.\
self.script_list_widget.set_sensitive(False)
gobject.timeout_add(self.NMAP_DELAY, self.script_list_timer_callback, nmap_process, callback)
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:
status = None
log.debug("Script interface: script_list_timer_callback %s" % repr(status))
log.debug("Script interface: script_list_timer_callback %s" % \
repr(status))
if status == True:
# Still running, schedule this timer to check again.
@@ -326,7 +338,8 @@ There was an error getting the list of scripts from Nmap. Try upgrading Nmap.\
def handle_initial_script_list_output(self, process):
process.stdout_file.seek(0)
try:
handler = ScriptHelpXMLContentHandler.parse_nmap_script_help(process.stdout_file)
handler = ScriptHelpXMLContentHandler.parse_nmap_script_help(
process.stdout_file)
except (ValueError, xml.sax.SAXParseException), e:
log.debug("--script-help parse exception: %s" % str(e))
return False
@@ -342,12 +355,14 @@ There was an error getting the list of scripts from Nmap. Try upgrading Nmap.\
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))
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):
for entry in get_script_entries(
handler.scripts_dir, handler.nselib_dir):
entries[entry.filename] = entry
self.liststore.clear()
@@ -367,7 +382,8 @@ There was an error getting the list of scripts from Nmap. Try upgrading Nmap.\
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))
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:
@@ -383,7 +399,8 @@ There was an error getting the list of scripts from Nmap. Try upgrading Nmap.\
def handle_update_script_list_output(self, process):
process.stdout_file.seek(0)
try:
handler = ScriptHelpXMLContentHandler.parse_nmap_script_help(process.stdout_file)
handler = ScriptHelpXMLContentHandler.parse_nmap_script_help(
process.stdout_file)
except (ValueError, xml.sax.SAXParseException), e:
log.debug("--script-help parse exception: %s" % str(e))
return False
@@ -422,29 +439,41 @@ There was an error getting the list of scripts from Nmap. Try upgrading Nmap.\
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)
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):
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."""
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
if arg_dict is None: # if there is parsing error args_dict holds none
self.arg_values.clear()
else:
for key in arg_dict.keys():
self.arg_values[key] = arg_dict[key]
def update_argument_values(self,raw_argument):
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\n\nA list of all installed scripts. Activate or deactivate a script by clicking the box next to the script name.")
self.description_help = _("Description\n\nThis 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\n\nA list of arguments that affect the selected script. Enter a value by clicking in the value field beside the argument name.")
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()
@@ -454,7 +483,8 @@ There was an error getting the list of scripts from Nmap. Try upgrading Nmap.\
return vbox
def make_script_list_widget(self):
"""Creates and packs widgets associated with left hand side of Interface."""
"""Creates and packs widgets associated with left hand side of
Interface."""
vbox = gtk.VBox()
scrolled_window = HIGScrolledWindow()
@@ -485,7 +515,8 @@ There was an error getting the list of scripts from Nmap. Try upgrading Nmap.\
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_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)
@@ -511,11 +542,12 @@ There was an error getting the list of scripts from Nmap. Try upgrading Nmap.\
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 = 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 = HIGButton(stock=gtk.STOCK_ADD)
add_file_button.connect("clicked", self.add_file_button_clicked_cb)
hbox.pack_end(add_file_button)
@@ -542,7 +574,7 @@ There was an error getting the list of scripts from Nmap. Try upgrading Nmap.\
else:
self.file_liststore.append([filename, True])
def strip_file_name(self,filename):
def strip_file_name(self, filename):
"""Removes a ".nse" extension from filename if present."""
if(filename.endswith(".nse")):
return filename[:-4]
@@ -579,8 +611,8 @@ There was an error getting the list of scripts from Nmap. Try upgrading Nmap.\
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")
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)
@@ -606,7 +638,7 @@ There was an error getting the list of scripts from Nmap. Try upgrading Nmap.\
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.pack_start(self.value, True)
val_col.add_attribute(self.value, "text", 1)
arg_window.add(arg_listview)
@@ -614,7 +646,7 @@ There was an error getting the list of scripts from Nmap. Try upgrading Nmap.\
return vbox
def value_edited_cb(self,cell,path,new_text,model):
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
@@ -637,21 +669,22 @@ There was an error getting the list of scripts from Nmap. Try upgrading Nmap.\
self.ops["--script-args"] = ",".join(self.arg_list)
self.update_command()
def selection_changed_cb(self,selection):
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:
check_value = model.get_value(model.get_iter(path),1)
entry = model.get_value(model.get_iter(path),2)
check_value = model.get_value(model.get_iter(path), 1)
entry = model.get_value(model.get_iter(path), 2)
self.set_description(entry)
self.populate_arg_list(entry)
self.focussedentry = entry #Remember the currently pointing script entry
# Remember the currently pointing script entry
self.focussedentry = entry
def update_help_ls_cb(self,widget,extra): # list of scripts
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):
def update_help_desc_cb(self, widget, extra):
"""Callback method for displaying description."""
self.help_buf.set_text(self.description_help)
@@ -672,14 +705,17 @@ There was an error getting the list of scripts from Nmap. Try upgrading Nmap.\
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)
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"))
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()
@@ -702,7 +738,7 @@ There was an error getting the list of scripts from Nmap. Try upgrading Nmap.\
self.remove_file_button.set_sensitive(False)
self.set_script_from_selection()
def set_description(self,entry):
def set_description(self, entry):
"""Sets the content that is to be displayed in the description box."""
self.text_buffer.set_text(u"")
@@ -711,20 +747,25 @@ 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")
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")
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)
self.text_buffer.insert(
self.text_buffer.get_end_iter(), "\n" + entry.url)
def populate_arg_list(self,entry):
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)
self.value.set_property('editable', True)
for arg in entry.arguments:
arg_name, arg_desc = arg
self.current_arguments.append(arg)

View File

@@ -128,8 +128,10 @@ import copy
from zenmapGUI.higwidgets.higwindows import HIGWindow
from zenmapGUI.higwidgets.higboxes import HIGVBox
from zenmapGUI.higwidgets.higbuttons import HIGButton, HIGToggleButton
from zenmapGUI.higwidgets.higboxes import HIGVBox, HIGHBox, HIGSpacer, hig_box_space_holder
from zenmapGUI.higwidgets.higlabels import HIGSectionLabel, HIGEntryLabel, HintWindow
from zenmapGUI.higwidgets.higboxes import HIGVBox, HIGHBox, HIGSpacer,\
hig_box_space_holder
from zenmapGUI.higwidgets.higlabels import HIGSectionLabel, HIGEntryLabel,\
HintWindow
from zenmapGUI.higwidgets.higtables import HIGTable
from zenmapGUI.higwidgets.higdialogs import HIGAlertDialog
@@ -161,14 +163,16 @@ class SearchParser(object):
self.search_gui = search_gui
self.search_dict = search_gui.search_dict
# We need to make an operator->searchkey mapping, since the search entry
# field and the search classes have different syntax.
# We need to make an operator->searchkey mapping, since the search
# entry field and the search classes have different syntax.
#
# NOTE: if you want to add a new search key not handled by the SearchResult
# class, you should add a new method match_CRITERIANAME to the SearchResult class.
# For example, if you'd like a "noodles" criteria, you need to create the method
# SearchResult.match_noodles(self, noodles_string). To see how searches are
# actually performed, start reading from the SearchResult.search() method.
# NOTE: if you want to add a new search key not handled by the
# SearchResult class, you should add a new method match_CRITERIANAME to
# the SearchResult class. For example, if you'd like a "noodles"
# criteria, you need to create the method
# SearchResult.match_noodles(self, noodles_string). To see how searches
# are actually performed, start reading from the SearchResult.search()
# method.
self.ops2keys = copy.deepcopy(search_keywords)
# This is not really an operator (see below)
@@ -198,16 +202,18 @@ class SearchParser(object):
else:
self.search_dict["keyword"] = [word]
# Check if we have any dir: operators in our map, and if so, add them to the
# search_gui object and remove them from the map. The dir: operator isn't a real
# operator, in a sense that it doesn't need to be processed by the
# SearchResult.search() function. It is needed only to create a new SearchDir
# object, which is then used to perform the actual search().
# Check if we have any dir: operators in our map, and if so, add them
# to the search_gui object and remove them from the map. The dir:
# operator isn't a real operator, in a sense that it doesn't need to be
# processed by the SearchResult.search() function. It is needed only to
# create a new SearchDir object, which is then used to perform the
# actual search().
if "dir" in self.search_dict:
self.search_gui.init_search_dirs(self.search_dict["dir"])
else:
self.search_gui.init_search_dirs([])
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
@@ -230,25 +236,28 @@ class SearchGUI(gtk.VBox, object):
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
# 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, 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))
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
# 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.
# 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()
@@ -286,42 +295,48 @@ Warning: The database of saved scans is not available. (%s.) Use \
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
# 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
# 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 = []):
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
# 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"])
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"])
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)
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"
# 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_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"))
@@ -341,13 +356,14 @@ Warning: The database of saved scans is not available. (%s.) Use \
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
# 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)
self.result_scrolled.set_policy(
gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
# Packing it all together
self.set_spacing(4)
@@ -366,21 +382,24 @@ Warning: The database of saved scans is not available. (%s.) Use \
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() == "":
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
# 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.
# 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
# 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
# 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:
@@ -389,19 +408,22 @@ Warning: The database of saved scans is not available. (%s.) Use \
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.
# (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)
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)
# 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]:
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:
@@ -410,8 +432,9 @@ Warning: The database of saved scans is not available. (%s.) Use \
# 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.
# 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)
@@ -450,7 +473,8 @@ Warning: The database of saved scans is not available. (%s.) Use \
def add_search_dir(self, dir):
if dir not in self.search_dirs:
self.search_dirs[dir] = SearchDir(dir, self.options["file_extension"])
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."""
@@ -459,10 +483,14 @@ Warning: The database of saved scans is not available. (%s.) Use \
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 = 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
@@ -488,8 +516,9 @@ the search data base option at the 'Search options' tab before start the search"
# 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)))
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)):
@@ -505,7 +534,6 @@ the search data base option at the 'Search options' tab before start the search"
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
@@ -554,11 +582,11 @@ the search data base option at the 'Search options' tab before start the search"
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."""
"""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
@@ -571,17 +599,18 @@ class Criterion(gtk.HBox):
# 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.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()
@@ -591,7 +620,8 @@ class Criterion(gtk.HBox):
# 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
# 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:
@@ -605,7 +635,8 @@ class Criterion(gtk.HBox):
break
# Create a subcriterion
self.subcriterion = self.new_subcriterion(self.default_operator, self.default_argument)
self.subcriterion = self.new_subcriterion(
self.default_operator, self.default_argument)
# The "add" and "remove" buttons
self.add_btn = HIGButton(" ", gtk.STOCK_ADD)
@@ -674,6 +705,7 @@ class Criterion(gtk.HBox):
operator = property(get_operator)
argument = property(get_argument)
class Subcriterion(gtk.HBox):
"""This class is a base class for all subcriterion types. Depending on the
criterion selected in the Criterion's ComboBox, a subclass of Subcriterion
@@ -685,9 +717,11 @@ class Subcriterion(gtk.HBox):
self.argument = ""
def value_changed(self):
"""Propagates the operator and the argument up to the Criterion parent."""
"""Propagates the operator and the argument up to the Criterion
parent."""
self.get_parent().value_changed(self.operator, self.argument)
class SimpleSubcriterion(Subcriterion):
"""This class represents all 'simple' criterion types that need only an
entry box in order to define the criterion."""
@@ -716,6 +750,7 @@ class SimpleSubcriterion(Subcriterion):
self.argument = widget.get_text()
self.value_changed()
class PortSubcriterion(Subcriterion):
"""This class shows the port criterion GUI."""
def __init__(self, operator="open", argument=""):
@@ -736,11 +771,12 @@ class PortSubcriterion(Subcriterion):
self.label = gtk.Label(" is ")
self.port_state_combo = gtk.combo_box_new_text()
states = ["open", "scanned", "closed", "filtered", "unfiltered", "open|filtered",
"closed|filtered"]
states = ["open", "scanned", "closed", "filtered", "unfiltered",
"open|filtered", "closed|filtered"]
for state in states:
self.port_state_combo.append_text(state)
self.port_state_combo.set_active(states.index(self.operator.replace("_", "|")))
self.port_state_combo.set_active(
states.index(self.operator.replace("_", "|")))
def _pack_widgets(self):
self.pack_start(self.entry, True)
@@ -759,6 +795,7 @@ class PortSubcriterion(Subcriterion):
self.operator = widget.get_active_text()
self.value_changed()
class DirSubcriterion(Subcriterion):
def __init__(self, operator="dir", argument=""):
Subcriterion.__init__(self)
@@ -797,13 +834,14 @@ class DirSubcriterion(Subcriterion):
self.argument = widget.get_text()
self.value_changed()
class DateSubcriterion(Subcriterion):
def __init__(self, operator="date", argument=""):
Subcriterion.__init__(self)
self.text2op = {"is" : "date",
"after" : "after",
"before" : "before"}
self.text2op = {"is": "date",
"after": "after",
"before": "before"}
self.operator = operator
@@ -811,7 +849,8 @@ class DateSubcriterion(Subcriterion):
self._pack_widgets()
self._connect_widgets()
# Count the fuzzy operators, so that we can append them to the argument later
# 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
@@ -821,9 +860,11 @@ class DateSubcriterion(Subcriterion):
self.argument = argument
elif re.match("[-|\+]\d+$", argument) != None:
# Convert the date from the "-n" notation into YYYY-MM-DD
parsed_date = datetime.date.fromordinal(datetime.date.today().toordinal() + int(argument))
parsed_date = datetime.date.fromordinal(
datetime.date.today().toordinal() + int(argument))
self.argument = argument
self.date = datetime.date(parsed_date.year, parsed_date.month, parsed_date.day)
self.date = datetime.date(
parsed_date.year, parsed_date.month, parsed_date.day)
self.minus_notation = True
else:
@@ -851,7 +892,8 @@ class DateSubcriterion(Subcriterion):
self.pack_start(self.date_button, True)
def _connect_widgets(self):
self.date_criterion_combo.connect("changed", self.date_criterion_changed)
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):
@@ -897,6 +939,7 @@ class DateSubcriterion(Subcriterion):
date = property(get_date, set_date)
_date = datetime.date.today()
class DateCalendar(gtk.Window, object):
def __init__(self):
gtk.Window.__init__(self, gtk.WINDOW_POPUP)
@@ -906,7 +949,7 @@ class DateCalendar(gtk.Window, object):
self.add(self.calendar)
def connect_calendar(self, update_button_cb):
self.calendar.connect("day-selected-double-click", \
self.calendar.connect("day-selected-double-click",
self.kill_calendar, update_button_cb)
def kill_calendar(self, widget, method):

View File

@@ -135,6 +135,7 @@ hildon = None
if is_maemo():
import hildon
class BaseSearchWindow(hildon.Window):
def __init__(self):
hildon.Window.__init__(self)
@@ -151,6 +152,7 @@ else:
def _pack_widgets(self):
self.vbox.set_border_width(4)
class SearchWindow(BaseSearchWindow, object):
def __init__(self, load_method, append_method):
BaseSearchWindow.__init__(self)
@@ -200,7 +202,8 @@ class SearchWindow(BaseSearchWindow, object):
def _connect_widgets(self):
# Double click on result, opens it
self.search_gui.result_view.connect("row-activated", self.open_selected)
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)
@@ -214,14 +217,16 @@ class SearchWindow(BaseSearchWindow, object):
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):
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):
def append_selected(self, widget=None, path=None, view_column=None,
extra=None):
# Append selected results
self.append_method(self.results)

View File

@@ -124,6 +124,7 @@ import gtk
from zenmapCore.TargetList import target_list
class TargetCombo(gtk.ComboBoxEntry):
def __init__(self):
gtk.ComboBoxEntry.__init__(self, gtk.ListStore(str), 0)
@@ -143,7 +144,7 @@ class TargetCombo(gtk.ComboBoxEntry):
t_list = target_list.get_target_list()
for target in t_list[:15]:
t_model.append([target.replace('\n','')])
t_model.append([target.replace('\n', '')])
def add_new_target(self, target):
target_list.add_target(target)

View File

@@ -144,6 +144,7 @@ from radialnet.util.integration import make_graph_from_hosts
SLOW_LIMIT = 1000
class TopologyPage(HIGVBox):
def __init__(self, inventory):
HIGVBox.__init__(self)
@@ -200,12 +201,14 @@ class TopologyPage(HIGVBox):
self.display_panel.pack_start(self.radialnet, True, True)
def add_scan(self, scan):
"""Parses a given XML file and adds the parsed result to the network inventory."""
"""Parses a given XML file and adds the parsed result to the network
inventory."""
self.network_inventory.add_scan(scan)
self.update_radialnet()
def update_radialnet(self):
"""Creates a graph from network inventory's host list and displays it."""
"""Creates a graph from network inventory's host list and displays
it."""
hosts_up = self.network_inventory.get_hosts_up()
self.slow_label.set_text(_("""\

View File

@@ -136,23 +136,24 @@ import gobject
gtk_version_major, gtk_version_minor, gtk_version_release = gtk.gtk_version
assert gtk_version_major == 2
def gtk_constant_name(group, value):
"""
Returns the (py)GTK+ name of a constant, given its group name
"""
group_response = { -1 : 'gtk.RESPONSE_NONE',
-2 : 'gtk.RESPONSE_REJECT',
-3 : 'gtk.RESPONSE_ACCEPT',
-4 : 'gtk.RESPONSE_DELETE_EVENT',
-5 : 'gtk.RESPONSE_OK',
-6 : 'gtk.RESPONSE_CANCEL',
-7 : 'gtk.RESPONSE_CLOSE',
-8 : 'gtk.RESPONSE_YES',
-9 : 'gtk.RESPONSE_NO',
-10 : 'gtk.RESPONSE_APPLY',
-11 : 'gtk.RESPONSE_HELP' }
group_response = {-1: 'gtk.RESPONSE_NONE',
-2: 'gtk.RESPONSE_REJECT',
-3: 'gtk.RESPONSE_ACCEPT',
-4: 'gtk.RESPONSE_DELETE_EVENT',
-5: 'gtk.RESPONSE_OK',
-6: 'gtk.RESPONSE_CANCEL',
-7: 'gtk.RESPONSE_CLOSE',
-8: 'gtk.RESPONSE_YES',
-9: 'gtk.RESPONSE_NO',
-10: 'gtk.RESPONSE_APPLY',
-11: 'gtk.RESPONSE_HELP'}
groups = {'response' : group_response}
groups = {'response': group_response}
return groups.get(group, {}).get(value, 'Error: constant value not found')

View File

@@ -130,6 +130,7 @@ __all__ = ['HIGHBox', 'HIGVBox']
import gtk
class HIGBox(gtk.Box):
def _pack_noexpand_nofill(self, widget):
self.pack_start(widget, expand=False, fill=False)
@@ -137,6 +138,7 @@ class HIGBox(gtk.Box):
def _pack_expand_fill(self, widget):
self.pack_start(widget, expand=True, fill=True)
class HIGHBox(gtk.HBox, HIGBox):
def __init__(self, homogeneous=False, spacing=12):
gtk.HBox.__init__(self, homogeneous, spacing)
@@ -145,6 +147,7 @@ class HIGHBox(gtk.HBox, HIGBox):
pack_label = HIGBox._pack_noexpand_nofill
pack_entry = HIGBox._pack_expand_fill
class HIGVBox(gtk.VBox, HIGBox):
def __init__(self, homogeneous=False, spacing=12):
gtk.VBox.__init__(self, homogeneous, spacing)
@@ -152,6 +155,7 @@ class HIGVBox(gtk.VBox, HIGBox):
# Packs a widget as a line, so it doesn't expand vertically
pack_line = HIGBox._pack_noexpand_nofill
class HIGSpacer(HIGHBox):
def __init__(self, widget=None):
HIGHBox.__init__(self)
@@ -166,5 +170,6 @@ class HIGSpacer(HIGHBox):
def get_child(self):
return self.child
def hig_box_space_holder():
return gtk.Label(" ")

View File

@@ -130,6 +130,7 @@ __all__ = ['HIGMixButton', 'HIGButton']
import gtk
class HIGMixButton (gtk.HBox):
def __init__(self, title, stock):
gtk.HBox.__init__(self, False, 4)
@@ -146,8 +147,9 @@ class HIGMixButton (gtk.HBox):
self.pack_start(self.align)
self.pack_start(self.hbox1)
class HIGButton (gtk.Button):
def __init__ (self, title="", stock=None):
def __init__(self, title="", stock=None):
if title and stock:
gtk.Button.__init__(self)
content = HIGMixButton(title, stock)
@@ -159,6 +161,7 @@ class HIGButton (gtk.Button):
else:
gtk.Button.__init__(self)
class HIGToggleButton(gtk.ToggleButton):
def __init__(self, title="", stock=None):
if title and stock:

View File

@@ -132,6 +132,7 @@ import gtk
from gtkutils import gtk_version_minor
class HIGDialog(gtk.Dialog):
"""
HIGFied Dialog
@@ -142,6 +143,7 @@ class HIGDialog(gtk.Dialog):
self.vbox.set_border_width(2)
self.vbox.set_spacing(6)
class HIGAlertDialog(gtk.MessageDialog):
"""
HIGfied Alert Dialog.

View File

@@ -130,6 +130,7 @@ import gtk
HIGTextEntry = gtk.Entry
class HIGPasswordEntry(HIGTextEntry):
"""
An entry that masks its text

View File

@@ -132,6 +132,7 @@ import gtk
from higboxes import HIGHBox, hig_box_space_holder
class HIGExpander(gtk.Expander):
def __init__(self, label):
gtk.Expander.__init__(self)

View File

@@ -130,6 +130,7 @@ __all__ = ['HIGFrame']
import gtk
class HIGFrame(gtk.Frame):
"""
Frame without border with bold label.

View File

@@ -126,10 +126,13 @@ higwidgets/higlabels.py
labels related classes
"""
__all__ = ['HIGSectionLabel', 'HIGHintSectionLabel', 'HIGEntryLabel', 'HIGDialogLabel']
__all__ = [
'HIGSectionLabel', 'HIGHintSectionLabel', 'HIGEntryLabel', 'HIGDialogLabel'
]
import gtk
class HIGSectionLabel(gtk.Label):
"""
Bold label, used to define sections
@@ -142,10 +145,11 @@ class HIGSectionLabel(gtk.Label):
self.set_alignment(0, 0.50)
self.set_line_wrap(True)
class HIGHintSectionLabel(gtk.HBox, object):
"""
Bold label used to define sections, with a little icon that shows up a hint when mouse is
over it.
Bold label used to define sections, with a little icon that shows up a hint
when mouse is over it.
"""
def __init__(self, text=None, hint=None):
gtk.HBox.__init__(self)
@@ -156,13 +160,15 @@ class HIGHintSectionLabel(gtk.HBox, object):
self.pack_start(self.label, False, False)
self.pack_start(self.hint, False, False, 5)
class Hint(gtk.EventBox, object):
def __init__(self, hint):
gtk.EventBox.__init__(self)
self.hint = hint
self.hint_image = gtk.Image()
self.hint_image.set_from_stock(gtk.STOCK_DIALOG_INFO, gtk.ICON_SIZE_SMALL_TOOLBAR)
self.hint_image.set_from_stock(
gtk.STOCK_DIALOG_INFO, gtk.ICON_SIZE_SMALL_TOOLBAR)
self.add(self.hint_image)
@@ -172,6 +178,7 @@ class Hint(gtk.EventBox, object):
hint_window = HintWindow(self.hint)
hint_window.show_all()
class HintWindow(gtk.Window):
def __init__(self, hint):
gtk.Window.__init__(self, gtk.WINDOW_POPUP)
@@ -208,6 +215,7 @@ class HIGEntryLabel(gtk.Label):
self.set_use_markup(True)
self.set_line_wrap(True)
class HIGDialogLabel(gtk.Label):
"""
Centered, line-wrappable label, usually used on dialogs.

View File

@@ -135,6 +135,7 @@ from higlabels import HIGEntryLabel
from higtables import HIGTable
from higentries import HIGTextEntry, HIGPasswordEntry
class HIGLoginDialog(HIGDialog):
"""
A dialog that asks for basic login information (username / password)

View File

@@ -133,8 +133,11 @@ class HIGNotebook(gtk.Notebook):
gtk.Notebook.__init__(self)
self.popup_enable()
class HIGClosableTabLabel(HIGHBox):
__gsignals__ = { 'close-clicked' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()) }
__gsignals__ = {
'close-clicked': (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ())
}
def __init__(self, label_text=""):
gobject.GObject.__init__(self)

View File

@@ -132,6 +132,7 @@ import gtk
from higboxes import HIGHBox
class HIGLabeledProgressBar(HIGHBox):
def __init__(self, label=None):
HIGHBox.__init__(self)

View File

@@ -130,6 +130,7 @@ __all__ = ['HIGScrolledWindow']
import gtk
class HIGScrolledWindow(gtk.ScrolledWindow):
def __init__(self):
gtk.ScrolledWindow.__init__(self)

View File

@@ -134,12 +134,14 @@ import gobject
from gtkutils import gobject_register
class HIGSpinnerImages:
def __init__(self):
"""This class holds list of GDK Pixbuffers.
- static_pixbufs is used for multiple static pixbuffers
- self.animated_pixbufs is used for the pixbuffers that make up the animation
- self.animated_pixbufs is used for the pixbuffers that make up the
animation
"""
dprint('HIGSpinnerImages::__init__')
@@ -182,7 +184,7 @@ class HIGSpinnerImages:
dprint('HIGSpinnerImages::set_rest_pixbuf')
if not self.static_pixbufs.has_key(name):
if name not in self.static_pixbufs:
raise StaticPixbufNotFound
# self.rest_pixbuf holds the *real* pixbuf, not it's name
@@ -322,6 +324,7 @@ class HIGSpinnerCache:
self.spinner_images.static_pixbufs[key_name].save(path_name,
image_format)
class HIGSpinner(gtk.EventBox):
"""Simple spinner, such as the one found in webbrowsers and file managers.
@@ -331,8 +334,8 @@ class HIGSpinner(gtk.EventBox):
* height, the height that will be set for the images
"""
__gsignals__ = { 'expose-event' : 'override',
'size-request' : 'override' }
__gsignals__ = {'expose-event': 'override',
'size-request': 'override'}
def __init__(self):
gtk.EventBox.__init__(self)
@@ -384,8 +387,8 @@ class HIGSpinner(gtk.EventBox):
if self.timer_task == 0:
self.current_pixbuf = self.cache.spinner_images.rest_pixbuf
else:
self.current_pixbuf = self.cache.spinner_images.animated_pixbufs\
[self.animated_pixbuf_index]
self.current_pixbuf = self.cache.spinner_images.animated_pixbufs[
self.animated_pixbuf_index]
def start(self):
"""Starts the animation"""
@@ -401,11 +404,11 @@ class HIGSpinner(gtk.EventBox):
self.timer_task = 0
self.queue_draw()
def stop(self):
"""Stops the animation
Do the same stuff as pause, but returns the animation to the beggining."""
Do the same stuff as pause, but returns the animation to the
beginning."""
self.pause()
self.animated_pixbuf_index = 0

View File

@@ -133,6 +133,7 @@ import gtk
#from higlabels import *
#from higentries import *
class HIGTable(gtk.Table):
"""
A HIGFied table
@@ -154,4 +155,4 @@ class HIGTable(gtk.Table):
self.attach(widget, x0, x, y0, y, xoptions=gtk.FILL)
def attach_entry(self, widget, x0, x, y0, y):
self.attach(widget, x0, x, y0, y, xoptions=gtk.FILL|gtk.EXPAND)
self.attach(widget, x0, x, y0, y, xoptions=gtk.FILL | gtk.EXPAND)

View File

@@ -130,6 +130,7 @@ __all__ = ['HIGTextView']
import gtk
class HIGTextView(gtk.TextView):
def __init__(self, text=''):
gtk.TextView.__init__(self)

View File

@@ -128,6 +128,7 @@ higwidgets/higwindows.py
import gtk
class HIGWindow(gtk.Window):
"""HIGFied Window"""
def __init__(self, type=gtk.WINDOW_TOPLEVEL):

View File

@@ -130,6 +130,7 @@ __all__ = ['HIGSpinner']
import gobject
def gobject_register(klass):
if gtk_version_minor < 8:
gobject.type_register(klass)