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:
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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())
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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."""
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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("<>")
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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')))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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."""
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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(_("""\
|
||||
|
||||
@@ -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')
|
||||
|
||||
|
||||
@@ -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(" ")
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -130,6 +130,7 @@ import gtk
|
||||
|
||||
HIGTextEntry = gtk.Entry
|
||||
|
||||
|
||||
class HIGPasswordEntry(HIGTextEntry):
|
||||
"""
|
||||
An entry that masks its text
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -130,6 +130,7 @@ __all__ = ['HIGFrame']
|
||||
|
||||
import gtk
|
||||
|
||||
|
||||
class HIGFrame(gtk.Frame):
|
||||
"""
|
||||
Frame without border with bold label.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -132,6 +132,7 @@ import gtk
|
||||
|
||||
from higboxes import HIGHBox
|
||||
|
||||
|
||||
class HIGLabeledProgressBar(HIGHBox):
|
||||
def __init__(self, label=None):
|
||||
HIGHBox.__init__(self)
|
||||
|
||||
@@ -130,6 +130,7 @@ __all__ = ['HIGScrolledWindow']
|
||||
|
||||
import gtk
|
||||
|
||||
|
||||
class HIGScrolledWindow(gtk.ScrolledWindow):
|
||||
def __init__(self):
|
||||
gtk.ScrolledWindow.__init__(self)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -130,6 +130,7 @@ __all__ = ['HIGTextView']
|
||||
|
||||
import gtk
|
||||
|
||||
|
||||
class HIGTextView(gtk.TextView):
|
||||
def __init__(self, text=''):
|
||||
gtk.TextView.__init__(self)
|
||||
|
||||
@@ -128,6 +128,7 @@ higwidgets/higwindows.py
|
||||
|
||||
import gtk
|
||||
|
||||
|
||||
class HIGWindow(gtk.Window):
|
||||
"""HIGFied Window"""
|
||||
def __init__(self, type=gtk.WINDOW_TOPLEVEL):
|
||||
|
||||
@@ -130,6 +130,7 @@ __all__ = ['HIGSpinner']
|
||||
|
||||
import gobject
|
||||
|
||||
|
||||
def gobject_register(klass):
|
||||
if gtk_version_minor < 8:
|
||||
gobject.type_register(klass)
|
||||
|
||||
Reference in New Issue
Block a user