diff --git a/zenmap/radialnet/__init__.py b/zenmap/radialnet/__init__.py index 1d0f3783e..3a4b048ee 100644 --- a/zenmap/radialnet/__init__.py +++ b/zenmap/radialnet/__init__.py @@ -119,4 +119,4 @@ # * * # ***************************************************************************/ -__all__ = ["bestwidgets", "core", "gui", "util"]; +__all__ = ["bestwidgets", "core", "gui", "util"] diff --git a/zenmap/radialnet/bestwidgets/boxes.py b/zenmap/radialnet/bestwidgets/boxes.py index cfba0e902..f37faa469 100644 --- a/zenmap/radialnet/bestwidgets/boxes.py +++ b/zenmap/radialnet/bestwidgets/boxes.py @@ -122,7 +122,6 @@ import gtk - class BWBox(gtk.Box): """ """ @@ -131,38 +130,32 @@ class BWBox(gtk.Box): """ self.pack_start(widget, True, True, padding) - def bw_pack_start_expand_nofill(self, widget, padding=0): """ """ self.pack_start(widget, True, False, padding) - def bw_pack_start_noexpand_nofill(self, widget, padding=0): """ """ self.pack_start(widget, False, False, padding) - def bw_pack_end_expand_fill(self, widget, padding=0): """ """ self.pack_end(widget, True, True, padding) - def bw_pack_end_expand_nofill(self, widget, padding=0): """ """ self.pack_end(widget, True, False, padding) - def bw_pack_end_noexpand_nofill(self, widget, padding=0): """ """ self.pack_end(widget, False, False, padding) - class BWHBox(gtk.HBox, BWBox): """ """ @@ -172,7 +165,6 @@ class BWHBox(gtk.HBox, BWBox): gtk.HBox.__init__(self, homogeneous, spacing) - class BWVBox(gtk.VBox, BWBox): """ """ @@ -182,7 +174,6 @@ class BWVBox(gtk.VBox, BWBox): gtk.VBox.__init__(self, homogeneous, spacing) - class BWStatusbar(gtk.Statusbar, BWBox): """ """ @@ -192,7 +183,6 @@ class BWStatusbar(gtk.Statusbar, BWBox): gtk.HBox.__init__(self, homogeneous, spacing) - class BWTable(gtk.Table, BWBox): """ """ @@ -207,14 +197,12 @@ class BWTable(gtk.Table, BWBox): self.__last_point = (0, 0) - def bw_set_spacing(self, spacing): """ """ self.set_row_spacings(spacing) self.set_col_spacings(spacing) - def bw_resize(self, rows, columns): """ """ @@ -223,11 +211,10 @@ class BWTable(gtk.Table, BWBox): self.resize(rows, columns) - def bw_attach_next(self, child, - xoptions=gtk.EXPAND|gtk.FILL, - yoptions=gtk.EXPAND|gtk.FILL, + xoptions=gtk.EXPAND | gtk.FILL, + yoptions=gtk.EXPAND | gtk.FILL, xpadding=0, ypadding=0): """ @@ -257,7 +244,6 @@ class BWTable(gtk.Table, BWBox): self.__last_point = (row, column) - class BWScrolledWindow(gtk.ScrolledWindow): """ """ diff --git a/zenmap/radialnet/bestwidgets/buttons.py b/zenmap/radialnet/bestwidgets/buttons.py index 010693f47..9990c5e7c 100644 --- a/zenmap/radialnet/bestwidgets/buttons.py +++ b/zenmap/radialnet/bestwidgets/buttons.py @@ -122,7 +122,6 @@ import gtk - class BWStockButton(gtk.Button): """ """ @@ -138,7 +137,6 @@ class BWStockButton(gtk.Button): self.set_image(self.__image) - class BWToggleStockButton(gtk.ToggleButton): """ """ diff --git a/zenmap/radialnet/bestwidgets/comboboxes.py b/zenmap/radialnet/bestwidgets/comboboxes.py index 8ff1b54aa..23d3d1fbe 100644 --- a/zenmap/radialnet/bestwidgets/comboboxes.py +++ b/zenmap/radialnet/bestwidgets/comboboxes.py @@ -123,7 +123,6 @@ import gtk import gobject - class BWChangeableComboBoxEntry(gtk.ComboBoxEntry): """ """ @@ -139,20 +138,17 @@ class BWChangeableComboBoxEntry(gtk.ComboBoxEntry): self.__last_active = None - def __changed(self, widget): """ """ if self.get_active() != -1: self.__last_active = self.get_active() - def bw_get_lenght(self): """ """ return len(self.__liststore) - def __entry_changed(self, widget): """ """ @@ -163,7 +159,6 @@ class BWChangeableComboBoxEntry(gtk.ComboBoxEntry): iter = self.get_model().get_iter((self.__last_active,)) self.__liststore.set_value(iter, 0, widget.get_text().strip()) - def bw_get_active(self): """ """ @@ -173,7 +168,6 @@ class BWChangeableComboBoxEntry(gtk.ComboBoxEntry): return self.get_active() - # testing widget if __name__ == "__main__": @@ -182,7 +176,6 @@ if __name__ == "__main__": """ combo.append_text('New') - window = gtk.Window() window.connect("destroy", lambda w: gtk.main_quit()) diff --git a/zenmap/radialnet/bestwidgets/expanders.py b/zenmap/radialnet/bestwidgets/expanders.py index 9647137e1..08da8b912 100644 --- a/zenmap/radialnet/bestwidgets/expanders.py +++ b/zenmap/radialnet/bestwidgets/expanders.py @@ -139,13 +139,11 @@ class BWExpander(gtk.Expander): self.add(self.__alignment) - def bw_set_label_text(self, text): """ """ self.__label.bw_set_text(text) - def bw_add(self, widget): """ """ @@ -154,7 +152,6 @@ class BWExpander(gtk.Expander): self.__alignment.add(widget) - def bw_no_padding(self): """ """ diff --git a/zenmap/radialnet/bestwidgets/frames.py b/zenmap/radialnet/bestwidgets/frames.py index ec0cb12bb..af5d2b0d5 100644 --- a/zenmap/radialnet/bestwidgets/frames.py +++ b/zenmap/radialnet/bestwidgets/frames.py @@ -122,7 +122,6 @@ import gtk - class BWFrame(gtk.Frame): """ """ @@ -141,20 +140,17 @@ class BWFrame(gtk.Frame): self.bw_set_label(label) - def bw_set_label(self, label): """ """ self.set_label("" + label + "") self.get_label_widget().set_use_markup(True) - def bw_add(self, widget): """ """ self.__alignment.add(widget) - def bw_remove(self, widget): """ """ diff --git a/zenmap/radialnet/bestwidgets/labels.py b/zenmap/radialnet/bestwidgets/labels.py index a4e078b05..646086568 100644 --- a/zenmap/radialnet/bestwidgets/labels.py +++ b/zenmap/radialnet/bestwidgets/labels.py @@ -122,7 +122,6 @@ import gtk - class BWLabel(gtk.Label): """ """ @@ -137,7 +136,6 @@ class BWLabel(gtk.Label): self.set_line_wrap(True) - class BWSectionLabel(gtk.Label): """ """ @@ -151,7 +149,6 @@ class BWSectionLabel(gtk.Label): self.set_alignment(0, 0.50) self.set_line_wrap(True) - def bw_set_text(self, text): """ """ diff --git a/zenmap/radialnet/bestwidgets/textview.py b/zenmap/radialnet/bestwidgets/textview.py index 27633f1c6..3a2650811 100644 --- a/zenmap/radialnet/bestwidgets/textview.py +++ b/zenmap/radialnet/bestwidgets/textview.py @@ -135,7 +135,6 @@ class BWTextView(BWScrolledWindow): self.__create_widgets() - def __create_widgets(self): """ """ @@ -144,25 +143,21 @@ class BWTextView(BWScrolledWindow): self.add_with_viewport(self.__textview) - def bw_set_auto_scroll(self, value): """ """ self.__auto_scroll = value - def bw_set_editable(self, editable): """ """ self.__textview.set_editable(False) - def bw_modify_font(self, font): """ """ self.__textview.modify_font(font) - def bw_set_text(self, text): """ """ @@ -171,27 +166,23 @@ class BWTextView(BWScrolledWindow): if self.__auto_scroll: self.bw_set_scroll_down() - def bw_get_text(self): """ """ return self.__textbuffer.get_text(self.__textbuffer.get_start_iter(), self.__textbuffer.get_end_iter()) - def bw_set_scroll_down(self): """ """ self.get_vadjustment().set_value(self.get_vadjustment().upper) - def bw_get_textbuffer(self): """ """ return self.__textbuffer - class BWTextEditor(BWScrolledWindow): """ """ @@ -205,7 +196,6 @@ class BWTextEditor(BWScrolledWindow): self.__create_widgets() - def __create_widgets(self): """ """ @@ -225,33 +215,28 @@ class BWTextEditor(BWScrolledWindow): self.add_with_viewport(self.__hbox) - def __expose(self, widget, event): """ """ # code to fix a gtk issue that don't show text correctly self.__hbox.check_resize() - def bw_set_auto_scroll(self, value): """ """ self.__auto_scroll = value - def bw_set_editable(self, editable): """ """ self.__textview.set_editable(False) - def bw_modify_font(self, font): """ """ self.__textview.modify_font(font) self.__lineview.modify_font(font) - def bw_set_text(self, text): """ """ @@ -273,14 +258,12 @@ class BWTextEditor(BWScrolledWindow): self.__textbuffer.set_text("") self.__linebuffer.set_text("") - def bw_get_text(self): """ """ return self.__textbuffer.get_text(self.__textbuffer.get_start_iter(), self.__textbuffer.get_end_iter()) - def bw_set_scroll_down(self): """ """ diff --git a/zenmap/radialnet/bestwidgets/windows.py b/zenmap/radialnet/bestwidgets/windows.py index 63ce36ac6..8f6599d48 100644 --- a/zenmap/radialnet/bestwidgets/windows.py +++ b/zenmap/radialnet/bestwidgets/windows.py @@ -125,7 +125,6 @@ from radialnet.bestwidgets import gtk_version_minor PRIMARY_TEXT_MARKUP = '%s' - class BWAlertDialog(gtk.MessageDialog): """ """ @@ -149,14 +148,12 @@ class BWAlertDialog(gtk.MessageDialog): if gtk_version_minor > 4: self.format_secondary_text(secondary_text) - def __destroy(self, dialog, id): """ """ self.destroy() - class BWWindow(gtk.Window): """ """ diff --git a/zenmap/radialnet/core/ArgvHandle.py b/zenmap/radialnet/core/ArgvHandle.py index d7bd4f28e..6459dde1f 100644 --- a/zenmap/radialnet/core/ArgvHandle.py +++ b/zenmap/radialnet/core/ArgvHandle.py @@ -130,7 +130,6 @@ class ArgvHandle: """ self.__argv = argv - def get_option(self, option): """ """ @@ -143,20 +142,17 @@ class ArgvHandle: return None - def has_option(self, option): """ """ return option in self.__argv - def get_last_value(self): """ """ return self.__argv[-1] - if __name__ == '__main__': import sys diff --git a/zenmap/radialnet/core/Coordinate.py b/zenmap/radialnet/core/Coordinate.py index 684c92d83..2b77b7895 100644 --- a/zenmap/radialnet/core/Coordinate.py +++ b/zenmap/radialnet/core/Coordinate.py @@ -141,31 +141,26 @@ class PolarCoordinate: self.__t = t """Angle (theta) of polar coordinate in radians""" - def get_theta(self): """ """ return math.degrees(self.__t) - def get_radius(self): """ """ return self.__r - def set_theta(self, t): """ """ self.__t = math.radians(t) - def set_radius(self, r): """ """ self.__r = r - def get_coordinate(self): """ Set polar coordinate @@ -174,7 +169,6 @@ class PolarCoordinate: """ return (self.__r, math.degrees(self.__t)) - def set_coordinate(self, r, t): """ Set polar coordinate @@ -186,7 +180,6 @@ class PolarCoordinate: self.__r = r self.__t = math.radians(t) - def to_cartesian(self): """ Convert polar in cartesian coordinate @@ -199,12 +192,10 @@ class PolarCoordinate: return (x, y) - class CartesianCoordinate: """ Class to implement a cartesian coordinate object """ - def __init__(self, x=0, y=0): """ Constructor method of CartesianCoordinate class @@ -218,7 +209,6 @@ class CartesianCoordinate: self.__y = y """Y component of cartesian coordinate""" - def get_coordinate(self): """ Get cartesian coordinate @@ -227,7 +217,6 @@ class CartesianCoordinate: """ return (self.__x, self.__y) - def set_coordinate(self, x, y): """ Set cartesian coordinate @@ -239,25 +228,24 @@ class CartesianCoordinate: self.__x = x self.__y = y - def to_polar(self): """ Convert cartesian in polar coordinate @rtype: tuple @return: polar coordinates (r, t) """ - r = math.sqrt(self.__x**2 + self.__y**2) + r = math.sqrt(self.__x ** 2 + self.__y ** 2) if self.__x > 0: if self.__y >= 0: - t = math.atan( self.__y / self.__x ) + t = math.atan(self.__y / self.__x) else: - t = math.atan( self.__y / self.__x ) + 2 * math.pi + t = math.atan(self.__y / self.__x) + 2 * math.pi elif self.__x < 0: - t = math.atan( self.__y / self.__x ) + math.pi + t = math.atan(self.__y / self.__x) + math.pi elif self.__x == 0: @@ -273,12 +261,11 @@ class CartesianCoordinate: return (r, t) - if __name__ == "__main__": # Testing application - polar = PolarCoordinate(1, math.pi) + polar = PolarCoordinate(1, math.pi) cartesian = CartesianCoordinate(-1, 0) print polar.to_cartesian() diff --git a/zenmap/radialnet/core/Graph.py b/zenmap/radialnet/core/Graph.py index 7bd89008c..8219cb0ae 100644 --- a/zenmap/radialnet/core/Graph.py +++ b/zenmap/radialnet/core/Graph.py @@ -135,15 +135,12 @@ class Node(object): self.__edges = [] """List of edges to other nodes""" - def get_data(self): return self.__data - def set_data(self, data): self.__data = data - def get_edge(self, dest): """ Return the edge connecting to dest, or None if none @@ -153,19 +150,16 @@ class Node(object): return edge return None - def get_edges(self): """ Return the list of edges """ return self.__edges - def add_edge(self, edge): self.__edges.append(edge) - class Edge: """ """ @@ -176,41 +170,34 @@ class Edge: self.__nodes = nodes self.__weights_mean = None - def get_nodes(self): """ """ return self.__nodes - def get_weights(self): """ """ return self.__weights - def set_weights(self, weights): """ """ self.__weights = weights self.__weights_mean = sum(self.__weights) / len(self.__weights) - def add_weight(self, weight): """ """ self.__weights.append(weight) self.__weights_mean = sum(self.__weights) / len(self.__weights) - def get_weights_mean(self): """ """ return self.__weights_mean - - class Graph: """ Network Graph class @@ -227,19 +214,16 @@ class Graph: self.__max_edge_mean_value = None self.__min_edge_mean_value = None - def set_nodes(self, nodes): """ """ self.__nodes = nodes - def get_nodes(self): """ """ return self.__nodes - def get_number_of_nodes(self): """ Get the number of nodes in graph @@ -248,7 +232,6 @@ class Graph: """ return len(self.__nodes) - def set_main_node(self, node): """ Set the main node @@ -257,7 +240,6 @@ class Graph: """ self.__main_node = node - def get_main_node(self): """ Get the main node @@ -266,7 +248,6 @@ class Graph: """ return self.__main_node - def set_connection(self, a, b, weight=None): """ Set node connections @@ -287,12 +268,13 @@ class Graph: edge.add_weight(weight) mean_weight = edge.get_weights_mean() - if self.__min_edge_mean_value is None or mean_weight < self.__min_edge_mean_value: + if (self.__min_edge_mean_value is None or + mean_weight < self.__min_edge_mean_value): self.__min_edge_mean_value = mean_weight - if self.__max_edge_mean_value is None or mean_weight > self.__max_edge_mean_value: + if (self.__max_edge_mean_value is None or + mean_weight > self.__max_edge_mean_value): self.__max_edge_mean_value = mean_weight - def get_edges(self): """ An iterator that yields all edges @@ -302,7 +284,6 @@ class Graph: if edge.get_nodes()[0] == node: yield edge - def get_node_connections(self, node): """ """ @@ -319,16 +300,12 @@ class Graph: return connections - def get_max_edge_mean_weight(self): """ """ return self.__max_edge_mean_value - def get_min_edge_mean_weight(self): """ """ return self.__min_edge_mean_value - - diff --git a/zenmap/radialnet/core/Info.py b/zenmap/radialnet/core/Info.py index 8bb24da21..2079c0d1e 100644 --- a/zenmap/radialnet/core/Info.py +++ b/zenmap/radialnet/core/Info.py @@ -122,7 +122,7 @@ import os -INFO = {'name' : 'RadialNet', +INFO = {'name': 'RadialNet', 'version': '0.44', 'website': 'http://www.dca.ufrn.br/~joaomedeiros/radialnet/', 'authors': ['João Paulo de Souza Medeiros'], diff --git a/zenmap/radialnet/core/Interpolation.py b/zenmap/radialnet/core/Interpolation.py index 8b1284d28..9dc285c68 100644 --- a/zenmap/radialnet/core/Interpolation.py +++ b/zenmap/radialnet/core/Interpolation.py @@ -136,7 +136,6 @@ class Linear2DInterpolator: self.__interpolated_points = [] """Interpolated points vector""" - def set_start_point(self, a, b): """ Set initial coordinate @@ -148,7 +147,6 @@ class Linear2DInterpolator: """ self.__start_point = (a, b) - def set_final_point(self, a, b): """ Set final coordinate @@ -159,7 +157,6 @@ class Linear2DInterpolator: """ self.__final_point = (a, b) - def get_weighed_points(self, number_of_pass, pass_vector): """ Return the vector of coordinates between the initial and final @@ -188,7 +185,6 @@ class Linear2DInterpolator: return self.__interpolated_points - def get_points(self, number_of_pass): """ Return the vector of coordinates between the initial and final @@ -213,7 +209,6 @@ class Linear2DInterpolator: return self.__interpolated_points - if __name__ == "__main__": # Testing application @@ -224,4 +219,3 @@ if __name__ == "__main__": i.set_final_point(1, 1) print len(i.get_points(10)), i.get_points(10) - diff --git a/zenmap/radialnet/core/XMLHandler.py b/zenmap/radialnet/core/XMLHandler.py index 191e6b703..a755b8097 100644 --- a/zenmap/radialnet/core/XMLHandler.py +++ b/zenmap/radialnet/core/XMLHandler.py @@ -124,14 +124,12 @@ import xml.sax.saxutils from xml.sax.xmlreader import AttributesImpl as Attributes - def convert_to_utf8(text): """ """ return text.encode('utf8', 'replace') - class XMLNode: """ """ @@ -143,70 +141,59 @@ class XMLNode: self.__attrs = dict() self.__children = [] - def set_text(self, text): """ """ self.__text = text - def get_text(self): """ """ return self.__text - def set_name(self, name): """ """ self.__name = name - def get_name(self): """ """ return self.__name - def add_attr(self, key, value): """ """ self.__attrs[key] = value - def add_child(self, child): """ """ self.__children.append(child) - def get_keys(self): """ """ return self.__attrs.keys() - def get_attr(self, attr): """ """ - if self.__attrs.has_key(attr): + if attr in self.__attrs: return self.__attrs[attr] return None - def get_attrs(self): """ """ return self.__attrs - def get_children(self): """ """ return self.__children - def query_children(self, name, attr, value, first=False, deep=False): """ """ @@ -216,7 +203,7 @@ class XMLNode: if child.get_name() == name: - if child.get_attrs().has_key(attr): + if attr in child.get_attrs(): c_value = child.get_attr(attr) @@ -243,7 +230,6 @@ class XMLNode: return result - def search_children(self, name, first=False, deep=False): """ """ @@ -276,7 +262,6 @@ class XMLNode: return result - class XMLWriter(xml.sax.saxutils.XMLGenerator): """ """ @@ -287,13 +272,11 @@ class XMLWriter(xml.sax.saxutils.XMLGenerator): self.__root = root - def set_root(self, root): """ """ self.__root = root - def write(self): """ """ @@ -301,7 +284,6 @@ class XMLWriter(xml.sax.saxutils.XMLGenerator): self.write_xml_node([self.__root]) self.endDocument() - def write_xml_node(self, root): """ """ @@ -317,7 +299,6 @@ class XMLWriter(xml.sax.saxutils.XMLGenerator): self.endElement(child.get_name()) - class XMLReader(xml.sax.ContentHandler): """ """ @@ -330,41 +311,35 @@ class XMLReader(xml.sax.ContentHandler): self.__file = file self.__root = None - self.__parser = xml.sax.make_parser(); - self.__parser.setContentHandler(self); - + self.__parser = xml.sax.make_parser() + self.__parser.setContentHandler(self) def set_file(self, file, root): """ """ self.__file = file - def get_file(self): """ """ return self.__file - def get_root(self): """ """ return self.__root - def parse(self): """ """ if self.__file != None: self.__parser.parse(self.__file) - def startDocument(self): """ """ pass - def startElement(self, name, attrs): """ """ @@ -384,7 +359,6 @@ class XMLReader(xml.sax.ContentHandler): self.__status.append(node) - def endElement(self, name): """ """ @@ -393,20 +367,17 @@ class XMLReader(xml.sax.ContentHandler): self.__text = "" self.__status.pop() - def endDocument(self): """ """ pass - def characters(self, text): """ """ self.__text += text - if __name__ == "__main__": import sys diff --git a/zenmap/radialnet/core/__init__.py b/zenmap/radialnet/core/__init__.py index 9c388f149..fb166b3fb 100644 --- a/zenmap/radialnet/core/__init__.py +++ b/zenmap/radialnet/core/__init__.py @@ -118,4 +118,3 @@ # * Nmap, and also available from https://svn.nmap.org/nmap/COPYING * # * * # ***************************************************************************/ - diff --git a/zenmap/radialnet/gui/Application.py b/zenmap/radialnet/gui/Application.py index f2365fa4a..a01c7392a 100644 --- a/zenmap/radialnet/gui/Application.py +++ b/zenmap/radialnet/gui/Application.py @@ -135,7 +135,6 @@ from radialnet.bestwidgets.boxes import * DIMENSION = (640, 480) - class Application(BWMainWindow): """ """ @@ -149,7 +148,6 @@ class Application(BWMainWindow): self.__create_widgets() - def __create_widgets(self): """ """ @@ -188,7 +186,6 @@ class Application(BWMainWindow): self.__fisheye.hide() self.__toolbar.disable_controls() - def parse_nmap_xml_file(self, file): """ """ @@ -217,7 +214,6 @@ class Application(BWMainWindow): return True - def start(self): """ """ diff --git a/zenmap/radialnet/gui/ControlWidget.py b/zenmap/radialnet/gui/ControlWidget.py index ca1a246f5..083ffd8e6 100644 --- a/zenmap/radialnet/gui/ControlWidget.py +++ b/zenmap/radialnet/gui/ControlWidget.py @@ -143,7 +143,6 @@ OPTIONS = ['address', REFRESH_RATE = 500 - class ControlWidget(BWVBox): """ """ @@ -157,7 +156,6 @@ class ControlWidget(BWVBox): self.__create_widgets() - def __create_widgets(self): """ """ @@ -179,6 +177,7 @@ def try_set_tooltip_text(widget, text): # The set_tooltip_text method was introduced in PyGTK 2.12. pass + class ControlAction(BWExpander): """ """ @@ -192,7 +191,6 @@ class ControlAction(BWExpander): self.__create_widgets() - def __create_widgets(self): """ """ @@ -253,7 +251,6 @@ class ControlAction(BWExpander): self.__region_color.set_no_show_all(True) self.__region_color.hide() - def __change_pointer(self, widget, pointer): """ """ @@ -265,14 +262,12 @@ class ControlAction(BWExpander): else: self.__region_color.hide() - def __change_region(self, widget): """ """ self.radialnet.set_region_color(self.__region_color.get_active()) - class ControlVariableWidget(gtk.DrawingArea): """ """ @@ -307,7 +302,6 @@ class ControlVariableWidget(gtk.DrawingArea): gobject.timeout_add(REFRESH_RATE, self.verify_value) - def verify_value(self): """ """ @@ -318,7 +312,6 @@ class ControlVariableWidget(gtk.DrawingArea): return True - def button_press(self, widget, event): """ """ @@ -331,7 +324,6 @@ class ControlVariableWidget(gtk.DrawingArea): self.__active_increment = True self.__increment_value() - def button_release(self, widget, event): """ """ @@ -342,7 +334,6 @@ class ControlVariableWidget(gtk.DrawingArea): self.queue_draw() - def motion_notify(self, widget, event): """ Drawing callback @@ -363,7 +354,6 @@ class ControlVariableWidget(gtk.DrawingArea): self.queue_draw() - def expose(self, widget, event): """ Drawing callback @@ -381,7 +371,6 @@ class ControlVariableWidget(gtk.DrawingArea): return True - def __draw(self): """ """ @@ -394,7 +383,7 @@ class ControlVariableWidget(gtk.DrawingArea): # draw line self.context.set_line_width(1) - self.context.set_dash([1,2]) + self.context.set_dash([1, 2]) self.context.move_to(self.__radius, yc + self.__radius) self.context.line_to(2 * xc - 5, @@ -402,7 +391,7 @@ class ControlVariableWidget(gtk.DrawingArea): self.context.stroke() # draw text - self.context.set_dash([1,0]) + self.context.set_dash([1, 0]) self.context.set_font_size(10) width = self.context.text_extents(self.__variable_name)[2] @@ -428,7 +417,6 @@ class ControlVariableWidget(gtk.DrawingArea): self.context.set_source_rgb(0.0, 0.0, 0.0) self.context.stroke() - def __button_is_clicked(self, pointer): """ """ @@ -440,7 +428,6 @@ class ControlVariableWidget(gtk.DrawingArea): return False - def __increment_value(self): """ """ @@ -453,20 +440,17 @@ class ControlVariableWidget(gtk.DrawingArea): gobject.timeout_add(self.__increment_time, self.__increment_value) - def set_value_function(self, value): """ """ self.__value = value - def set_update_function(self, update): """ """ self.__update = update - class ControlVariable(BWHBox): """ """ @@ -485,7 +469,6 @@ class ControlVariable(BWHBox): self.__create_widgets() - def __create_widgets(self): """ """ @@ -516,14 +499,12 @@ class ControlVariable(BWHBox): self.bw_pack_start_expand_fill(self.__control) self.bw_pack_start_noexpand_nofill(self.__right_button) - def __pressed(self, widget, increment): """ """ self.__increment = True self.__increment_function(increment) - def __increment_function(self, increment): """ """ @@ -536,15 +517,12 @@ class ControlVariable(BWHBox): self.__increment_function, increment) - def __released(self, widget): """ """ self.__increment = False - - class ControlFisheye(BWVBox): """ """ @@ -559,7 +537,6 @@ class ControlFisheye(BWVBox): self.__create_widgets() - def __create_widgets(self): """ """ @@ -606,7 +583,6 @@ class ControlFisheye(BWVBox): gobject.timeout_add(REFRESH_RATE, self.__update_fisheye) - def __update_fisheye(self): """ """ @@ -648,7 +624,6 @@ class ControlFisheye(BWVBox): return True - def active_fisheye(self): """ """ @@ -656,13 +631,11 @@ class ControlFisheye(BWVBox): self.__change_ring() self.__change_interest() - def deactive_fisheye(self): """ """ self.radialnet.set_fisheye(False) - def __change_ring(self, widget=None): """ """ @@ -671,7 +644,6 @@ class ControlFisheye(BWVBox): else: self.__ring.set_value(self.radialnet.get_fisheye_ring()) - def __change_interest(self, widget=None): """ """ @@ -680,7 +652,6 @@ class ControlFisheye(BWVBox): else: self.__interest.set_value(self.radialnet.get_fisheye_interest()) - def __change_spread(self, widget=None): """ """ @@ -690,7 +661,6 @@ class ControlFisheye(BWVBox): self.__spread.set_value(self.radialnet.get_fisheye_spread()) - class ControlInterpolation(BWExpander): """ """ @@ -703,14 +673,14 @@ class ControlInterpolation(BWExpander): self.__create_widgets() - def __create_widgets(self): """ """ self.__vbox = BWVBox() self.__cartesian_radio = gtk.RadioButton(None, _('Cartesian')) - self.__polar_radio = gtk.RadioButton(self.__cartesian_radio, _('Polar')) + self.__polar_radio = gtk.RadioButton( + self.__cartesian_radio, _('Polar')) self.__cartesian_radio.connect('toggled', self.__change_system, INTERPOLATION_CARTESIAN) @@ -741,7 +711,6 @@ class ControlInterpolation(BWExpander): gobject.timeout_add(REFRESH_RATE, self.__update_animation) - def __update_animation(self): """ """ @@ -755,7 +724,6 @@ class ControlInterpolation(BWExpander): return True - def __change_system(self, widget, value): """ """ @@ -769,7 +737,6 @@ class ControlInterpolation(BWExpander): else: self.__polar_radio.set_active(True) - def __change_frames(self, widget): """ """ @@ -777,7 +744,6 @@ class ControlInterpolation(BWExpander): self.__frames.set_value(self.radialnet.get_number_of_frames()) - class ControlLayout(BWExpander): """ """ @@ -790,7 +756,6 @@ class ControlLayout(BWExpander): self.__create_widgets() - def __create_widgets(self): """ """ @@ -811,7 +776,6 @@ class ControlLayout(BWExpander): self.__check_layout() - def __check_layout(self): """ """ @@ -823,14 +787,12 @@ class ControlLayout(BWExpander): return True - def __force_update(self, widget): """ """ self.__fisheye_ring = self.radialnet.get_fisheye_ring() self.radialnet.update_layout() - def __change_layout(self, widget): """ """ @@ -841,7 +803,6 @@ class ControlLayout(BWExpander): self.__check_layout() - class ControlRingGap(BWVBox): """ """ @@ -854,7 +815,6 @@ class ControlRingGap(BWVBox): self.__create_widgets() - def __create_widgets(self): """ """ @@ -878,7 +838,6 @@ class ControlRingGap(BWVBox): self.bw_pack_start_noexpand_nofill(self.__radius) self.bw_pack_start_noexpand_nofill(self.__lower_hbox) - def __change_lower(self, widget): """ """ @@ -886,7 +845,6 @@ class ControlRingGap(BWVBox): self.__adjustment.set_value(self.radialnet.get_min_ring_gap()) - class ControlOptions(BWScrolledWindow): """ """ @@ -902,7 +860,6 @@ class ControlOptions(BWScrolledWindow): self.__create_widgets() - def __create_widgets(self): """ """ @@ -943,23 +900,23 @@ class ControlOptions(BWScrolledWindow): gobject.timeout_add(REFRESH_RATE, self.__update_options) - def __update_options(self): """ """ model = self.__liststore model[OPTIONS.index('address')][0] = self.radialnet.get_show_address() - model[OPTIONS.index('hostname')][0] = self.radialnet.get_show_hostname() + model[OPTIONS.index('hostname')][0] = \ + self.radialnet.get_show_hostname() model[OPTIONS.index('icon')][0] = self.radialnet.get_show_icon() model[OPTIONS.index('latency')][0] = self.radialnet.get_show_latency() model[OPTIONS.index('ring')][0] = self.radialnet.get_show_ring() model[OPTIONS.index('region')][0] = self.radialnet.get_show_region() - model[OPTIONS.index('slow in/out')][0] = self.radialnet.get_slow_inout() + model[OPTIONS.index('slow in/out')][0] = \ + self.radialnet.get_slow_inout() return True - def __change_option(self, cell, option, model): """ """ @@ -988,7 +945,6 @@ class ControlOptions(BWScrolledWindow): self.radialnet.set_slow_inout(model[option][0]) - class ControlView(BWExpander): """ """ @@ -1002,7 +958,6 @@ class ControlView(BWExpander): self.__create_widgets() - def __create_widgets(self): """ """ @@ -1026,7 +981,6 @@ class ControlView(BWExpander): self.bw_add(self.__vbox) - class ControlNavigation(gtk.DrawingArea): """ """ @@ -1047,12 +1001,12 @@ class ControlNavigation(gtk.DrawingArea): self.__move_position = (0, 0) self.__move_addition = [(-1, 0), - (-1,-1), - ( 0,-1), - ( 1,-1), - ( 1, 0), - ( 1, 1), - ( 0, 1), + (-1, -1), + (0, -1), + (1, -1), + (1, 0), + (1, 1), + (0, 1), (-1, 1)] self.__move_factor = 1 @@ -1086,7 +1040,6 @@ class ControlNavigation(gtk.DrawingArea): self.__rotate_node.set_coordinate(40, self.radialnet.get_rotation()) - def key_press(self, widget, event): """ """ @@ -1096,7 +1049,6 @@ class ControlNavigation(gtk.DrawingArea): return True - def key_release(self, widget, event): """ """ @@ -1106,13 +1058,11 @@ class ControlNavigation(gtk.DrawingArea): return True - def enter_notify(self, widget, event): """ """ return False - def leave_notify(self, widget, event): """ """ @@ -1120,7 +1070,6 @@ class ControlNavigation(gtk.DrawingArea): return False - def button_press(self, widget, event): """ Drawing callback @@ -1159,7 +1108,6 @@ class ControlNavigation(gtk.DrawingArea): return False - def button_release(self, widget, event): """ Drawing callback @@ -1181,7 +1129,6 @@ class ControlNavigation(gtk.DrawingArea): return False - def motion_notify(self, widget, event): """ Drawing callback @@ -1213,7 +1160,6 @@ class ControlNavigation(gtk.DrawingArea): return False - def expose(self, widget, event): """ Drawing callback @@ -1231,7 +1177,6 @@ class ControlNavigation(gtk.DrawingArea): return False - def __draw_rotate_control(self): """ """ @@ -1251,14 +1196,14 @@ class ControlNavigation(gtk.DrawingArea): self.context.stroke() # draw arc - self.context.set_dash([1,2]) + self.context.set_dash([1, 2]) self.context.arc(xc, yc, 40, 0, 2 * math.pi) self.context.set_source_rgb(0.0, 0.0, 0.0) self.context.set_line_width(1) self.context.stroke() # draw node - self.context.set_dash([1,0]) + self.context.set_dash([1, 0]) self.context.arc(xc + x, yc - y, self.__rotate_radius, 0, 2 * math.pi) if self.__rotating == True: @@ -1274,14 +1219,13 @@ class ControlNavigation(gtk.DrawingArea): return False - def __draw_move_control(self): """ """ xc, yc = self.__center_of_widget pc = PolarCoordinate() - self.context.set_dash([1,1]) + self.context.set_dash([1, 1]) self.context.arc(xc, yc, 23, 0, 2 * math.pi) self.context.set_source_rgb(0.0, 0.0, 0.0) self.context.set_line_width(1) @@ -1292,13 +1236,14 @@ class ControlNavigation(gtk.DrawingArea): pc.set_coordinate(23, 45 * i) x, y = pc.to_cartesian() - self.context.set_dash([1,1]) + self.context.set_dash([1, 1]) self.context.move_to(xc, yc) self.context.line_to(xc + x, yc - y) self.context.stroke() - self.context.set_dash([1,0]) - self.context.arc(xc + x, yc - y, self.__move_radius, 0, 2 * math.pi) + self.context.set_dash([1, 0]) + self.context.arc( + xc + x, yc - y, self.__move_radius, 0, 2 * math.pi) if i == self.__moving: self.context.set_source_rgb(0.0, 0.0, 0.0) @@ -1322,7 +1267,6 @@ class ControlNavigation(gtk.DrawingArea): return False - def __draw(self): """ Drawing method @@ -1338,7 +1282,6 @@ class ControlNavigation(gtk.DrawingArea): return False - def __move_in_direction(self, direction): """ """ @@ -1360,7 +1303,6 @@ class ControlNavigation(gtk.DrawingArea): return False - def __rotate_is_clicked(self, pointer): """ """ @@ -1375,7 +1317,6 @@ class ControlNavigation(gtk.DrawingArea): return False - def __center_is_clicked(self, pointer): """ """ @@ -1388,7 +1329,6 @@ class ControlNavigation(gtk.DrawingArea): return False - def __move_is_clicked(self, pointer): """ """ @@ -1409,5 +1349,3 @@ class ControlNavigation(gtk.DrawingArea): return i return None - - diff --git a/zenmap/radialnet/gui/Dialogs.py b/zenmap/radialnet/gui/Dialogs.py index 47f240a00..89f7e44d3 100644 --- a/zenmap/radialnet/gui/Dialogs.py +++ b/zenmap/radialnet/gui/Dialogs.py @@ -126,7 +126,6 @@ from radialnet.core.Info import INFO from radialnet.gui.Image import Pixmaps - class AboutDialog(gtk.AboutDialog): """ """ @@ -146,7 +145,6 @@ class AboutDialog(gtk.AboutDialog): self.connect('response', self.__destroy) - def __destroy(self, dialog, id): """ """ diff --git a/zenmap/radialnet/gui/HostsViewer.py b/zenmap/radialnet/gui/HostsViewer.py index 4a1cf26e8..657acc31c 100644 --- a/zenmap/radialnet/gui/HostsViewer.py +++ b/zenmap/radialnet/gui/HostsViewer.py @@ -138,7 +138,6 @@ DIMENSION = (700, 400) IP_RE = '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$' - class HostsViewer(BWMainWindow): """ """ @@ -155,7 +154,6 @@ class HostsViewer(BWMainWindow): self.__create_widgets() - def __create_widgets(self): """ """ @@ -170,8 +168,6 @@ class HostsViewer(BWMainWindow): self.add(self.__panel) - - def change_notebook(self, node): """ """ @@ -187,7 +183,6 @@ class HostsViewer(BWMainWindow): self.__panel.add2(self.__view) - class HostsList(gtk.ScrolledWindow): """ """ @@ -203,7 +198,6 @@ class HostsList(gtk.ScrolledWindow): self.__create_widgets() - def __create_widgets(self): """ """ @@ -239,16 +233,16 @@ class HostsList(gtk.ScrolledWindow): column = gtk.TreeViewColumn(HOSTS_HEADER[i], self.__cell, - text = i) + text=i) self.__hosts_column.append(column) self.__hosts_column[i].set_reorderable(True) self.__hosts_column[i].set_resizable(True) self.__hosts_column[i].set_attributes(self.__cell, - text = i, - background = 3, - editable = 4) + text=i, + background=3, + editable=4) self.__hosts_treeview.append_column(self.__hosts_column[2]) @@ -262,7 +256,6 @@ class HostsList(gtk.ScrolledWindow): self.__hosts_treeview.set_cursor((0,)) self.__cursor_callback(self.__hosts_treeview) - def __cursor_callback(self, widget): """ """ @@ -276,7 +269,6 @@ class HostsList(gtk.ScrolledWindow): self.__parent.change_notebook(node) - def __host_sort(self, treemodel, iter1, iter2): """ """ diff --git a/zenmap/radialnet/gui/Image.py b/zenmap/radialnet/gui/Image.py index 814fac9c8..5876d957b 100644 --- a/zenmap/radialnet/gui/Image.py +++ b/zenmap/radialnet/gui/Image.py @@ -128,7 +128,7 @@ from zenmapCore.Paths import Path FORMAT_RGBA = 4 -FORMAT_RGB = 3 +FORMAT_RGB = 3 def get_pixels_for_cairo_image_surface(pixbuf): @@ -144,16 +144,16 @@ def get_pixels_for_cairo_image_surface(pixbuf): j = 0 while i < len(pixbuf.get_pixels()): - b, g, r = pixbuf.get_pixels()[i:i+FORMAT_RGB] + b, g, r = pixbuf.get_pixels()[i:i + FORMAT_RGB] if format == FORMAT_RGBA: a = pixbuf.get_pixels()[i + FORMAT_RGBA - 1] elif format == FORMAT_RGB: a = '\xff' else: - raise TypeError, 'unknown image format' + raise TypeError('unknown image format') - data[j:j+FORMAT_RGBA] = array.ArrayType('c', [r, g, b, a]) + data[j:j + FORMAT_RGBA] = array.ArrayType('c', [r, g, b, a]) i += format j += FORMAT_RGBA @@ -170,13 +170,11 @@ class Image: self.__path = path self.__cache = dict() - def set_path(self, path): """ """ self.__path = path - def get_pixbuf(self, icon, image_type='png'): """ """ @@ -186,11 +184,11 @@ class Image: if icon + image_type not in self.__cache.keys(): file = self.get_icon(icon, image_type) - self.__cache[icon + image_type] = gtk.gdk.pixbuf_new_from_file(file) + self.__cache[icon + image_type] = \ + gtk.gdk.pixbuf_new_from_file(file) return self.__cache[icon + image_type] - def get_icon(self, icon, image_type='png'): """ """ @@ -200,7 +198,6 @@ class Image: return os.path.join(self.__path, icon + "." + image_type) - class Pixmaps(Image): """ """ @@ -210,7 +207,6 @@ class Pixmaps(Image): Image.__init__(self, os.path.join(Path.pixmaps_dir, "radialnet")) - class Icons(Image): """ """ @@ -220,7 +216,6 @@ class Icons(Image): Image.__init__(self, os.path.join(Path.pixmaps_dir, "radialnet")) - class Application(Image): """ """ diff --git a/zenmap/radialnet/gui/NodeNotebook.py b/zenmap/radialnet/gui/NodeNotebook.py index a4b629ade..ee2521dda 100644 --- a/zenmap/radialnet/gui/NodeNotebook.py +++ b/zenmap/radialnet/gui/NodeNotebook.py @@ -129,27 +129,27 @@ from radialnet.bestwidgets.labels import * from radialnet.bestwidgets.textview import * -PORTS_HEADER = [_('Port'), _('Protocol'), _('State'), _('Service'), _('Method')] +PORTS_HEADER = [ + _('Port'), _('Protocol'), _('State'), _('Service'), _('Method')] EXTRAPORTS_HEADER = [_('Count'), _('State'), _('Reasons')] -SERVICE_COLORS = {'open' : '#ffd5d5', - 'closed' : '#d5ffd5', - 'filtered' : '#ffffd5', - 'unfiltered' : '#ffd5d5', - 'open|filtered' : '#ffd5d5', - 'closed|filtered' : '#d5ffd5'} +SERVICE_COLORS = {'open': '#ffd5d5', + 'closed': '#d5ffd5', + 'filtered': '#ffffd5', + 'unfiltered': '#ffd5d5', + 'open|filtered': '#ffd5d5', + 'closed|filtered': '#d5ffd5'} UNKNOWN_SERVICE_COLOR = '#d5d5d5' TRACE_HEADER = [_('TTL'), _('RTT'), _('IP'), _('Hostname')] -TRACE_TEXT = _("""\ -Traceroute on port %s/%s totalized %d known hops.\ -""") +TRACE_TEXT = _( + "Traceroute on port %s/%s totalized %d known hops.") NO_TRACE_TEXT = _("No traceroute information available.") -HOP_COLOR = {'known' : '#ffffff', - 'unknown' : '#cccccc'} +HOP_COLOR = {'known': '#ffffff', + 'unknown': '#cccccc'} SYSTEM_ADDRESS_TEXT = "[%s] %s" @@ -162,6 +162,7 @@ TCP_SEQ_NOTE = _("""\ * TCP sequence index equal to %d and difficulty is "%s".\ """) + def get_service_color(state): color = SERVICE_COLORS.get(state) if color is None: @@ -182,7 +183,6 @@ class NodeNotebook(gtk.Notebook): self.__create_widgets() - def __create_widgets(self): """ """ @@ -197,7 +197,6 @@ class NodeNotebook(gtk.Notebook): self.append_page(self.__trace_page, BWLabel(_('Traceroute'))) - class ServicesPage(gtk.Notebook): """ """ @@ -213,7 +212,6 @@ class ServicesPage(gtk.Notebook): self.__create_widgets() - def __create_widgets(self): """ """ @@ -256,13 +254,13 @@ class ServicesPage(gtk.Notebook): color = get_service_color(port['state']['state']) - if port['service'].has_key('name'): + if 'name' in port['service']: service_name = port['service']['name'] else: service_name = _('') - if port['service'].has_key('method'): + if 'method' in port['service']: service_method = port['service']['method'] else: @@ -330,7 +328,7 @@ class ServicesPage(gtk.Notebook): column = gtk.TreeViewColumn(PORTS_HEADER[i], self.__cell, - text = i) + text=i) self.__ports_column.append(column) @@ -338,9 +336,9 @@ class ServicesPage(gtk.Notebook): self.__ports_column[i].set_resizable(True) self.__ports_column[i].set_sort_column_id(i) self.__ports_column[i].set_attributes(self.__cell, - text = i, - background = 5, - editable = 6) + text=i, + background=5, + editable=6) self.__ports_treeview.append_column(self.__ports_column[i]) @@ -364,12 +362,9 @@ class ServicesPage(gtk.Notebook): color = get_service_color(xports['state']) number_of_xports += xports['count'] - reference = self.__xports_store.append(None, - [xports['count'], - xports['state'], - ", ".join(xports['reason']), - color, - True]) + reference = self.__xports_store.append( + None, [xports['count'], xports['state'], + ", ".join(xports['reason']), color, True]) for xreason in xports['all_reason']: self.__xports_store.append(reference, @@ -385,7 +380,7 @@ class ServicesPage(gtk.Notebook): column = gtk.TreeViewColumn(EXTRAPORTS_HEADER[i], self.__cell, - text = i) + text=i) self.__xports_column.append(column) @@ -393,9 +388,9 @@ class ServicesPage(gtk.Notebook): self.__xports_column[i].set_resizable(True) self.__xports_column[i].set_sort_column_id(i) self.__xports_column[i].set_attributes(self.__cell, - text = i, - background = 3, - editable = 4) + text=i, + background=3, + editable=4) self.__xports_treeview.append_column(self.__xports_column[i]) @@ -411,7 +406,6 @@ class ServicesPage(gtk.Notebook): if len(self.__text) > 0: self.__select_combobox.set_active(0) - def __change_text_value(self, widget): """ """ @@ -433,7 +427,6 @@ class SystemPage(BWScrolledWindow): self.__create_widgets() - def __create_widgets(self): """ """ @@ -516,7 +509,8 @@ class SystemPage(BWScrolledWindow): sequences = self.__node.get_info('sequences') if len(sequences) > 0: - self.__sequences_frame.bw_add(self.__create_sequences_widget(sequences)) + self.__sequences_frame.bw_add( + self.__create_sequences_widget(sequences)) # operating system information widgets self.__os = gtk.Notebook() @@ -525,7 +519,7 @@ class SystemPage(BWScrolledWindow): if os != None: - if os.has_key('matches'): + if 'matches' in os: self.__match_scroll = BWScrolledWindow() @@ -550,15 +544,15 @@ class SystemPage(BWScrolledWindow): column = gtk.TreeViewColumn(OSMATCH_HEADER[i], self.__cell, - text = i) + text=i) self.__match_column.append(column) self.__match_column[i].set_reorderable(True) self.__match_column[i].set_resizable(True) self.__match_column[i].set_attributes(self.__cell, - text = i, - editable = 3) + text=i, + editable=3) self.__match_column[i].set_sort_column_id(i) self.__match_treeview.append_column(self.__match_column[i]) @@ -567,7 +561,7 @@ class SystemPage(BWScrolledWindow): self.__os.append_page(self.__match_scroll, BWLabel(_('Match'))) - if os.has_key('classes'): + if 'classes' in os: self.__class_scroll = BWScrolledWindow() @@ -584,7 +578,7 @@ class SystemPage(BWScrolledWindow): os_gen = '' - if os_class.has_key('os_gen'): + if 'os_gen' in os_class: os_gen = os_class['os_gen'] self.__class_store.append([os_class['accuracy'], @@ -600,15 +594,15 @@ class SystemPage(BWScrolledWindow): column = gtk.TreeViewColumn(OSCLASS_HEADER[i], self.__cell, - text = i) + text=i) self.__class_column.append(column) self.__class_column[i].set_reorderable(True) self.__class_column[i].set_resizable(True) self.__class_column[i].set_attributes(self.__cell, - text = i, - editable = 5) + text=i, + editable=5) self.__class_column[i].set_sort_column_id(i) self.__class_treeview.append_column(self.__class_column[i]) @@ -630,7 +624,7 @@ class SystemPage(BWScrolledWindow): self.__fp_vbox = BWVBox() - if os.has_key('used_ports'): + if 'used_ports' in os: used_ports = os['used_ports'] @@ -692,7 +686,8 @@ class SystemPage(BWScrolledWindow): tcp_note.set_selectable(True) tcp_note.set_line_wrap(False) tcp_note.set_alignment(1.0, 0.5) - tcp_note.set_markup(TCP_SEQ_NOTE % (tcp['index'], tcp['difficulty'])) + tcp_note.set_markup( + TCP_SEQ_NOTE % (tcp['index'], tcp['difficulty'])) table.attach(tcp_note, 0, 3, 4, 5) @@ -733,8 +728,6 @@ class SystemPage(BWScrolledWindow): return table - - class TraceroutePage(BWVBox): """ """ @@ -748,7 +741,6 @@ class TraceroutePage(BWVBox): self.__create_widgets() - def __create_widgets(self): """ """ @@ -805,23 +797,22 @@ class TraceroutePage(BWVBox): HOP_COLOR['unknown'], True]) - self.__trace_column = list() for i in range(len(TRACE_HEADER)): column = gtk.TreeViewColumn(TRACE_HEADER[i], self.__cell, - text = i) + text=i) self.__trace_column.append(column) self.__trace_column[i].set_reorderable(True) self.__trace_column[i].set_resizable(True) self.__trace_column[i].set_attributes(self.__cell, - text = i, - background = 4, - editable = 5) + text=i, + background=4, + editable=5) self.__trace_treeview.append_column(self.__trace_column[i]) diff --git a/zenmap/radialnet/gui/NodeWindow.py b/zenmap/radialnet/gui/NodeWindow.py index 0e8d23c32..ace406d7c 100644 --- a/zenmap/radialnet/gui/NodeWindow.py +++ b/zenmap/radialnet/gui/NodeWindow.py @@ -151,7 +151,6 @@ class NodeWindow(BWWindow): self.__icon = Application() self.__create_widgets() - def __create_widgets(self): """ """ @@ -168,7 +167,8 @@ class NodeWindow(BWWindow): self.__color_image.set_from_file(self.__icon.get_icon('border')) self.__color_box.add(self.__color_image) self.__color_box.set_size_request(15, 15) - r, g, b = drawing.cairo_to_gdk_color(self.__node.get_draw_info('color')) + r, g, b = drawing.cairo_to_gdk_color( + self.__node.get_draw_info('color')) self.__color_box.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(r, g, b)) # title with the node ip and hostname diff --git a/zenmap/radialnet/gui/RadialNet.py b/zenmap/radialnet/gui/RadialNet.py index 7a8b2a21e..742c4e8d1 100644 --- a/zenmap/radialnet/gui/RadialNet.py +++ b/zenmap/radialnet/gui/RadialNet.py @@ -139,9 +139,9 @@ from radialnet.gui.Image import Icons, get_pixels_for_cairo_image_surface from zenmapCore.BasePaths import fs_enc REGION_COLORS = [(1.0, 0.0, 0.0), (1.0, 1.0, 0.0), (0.0, 1.0, 0.0)] -REGION_RED = 0 +REGION_RED = 0 REGION_YELLOW = 1 -REGION_GREEN = 2 +REGION_GREEN = 2 SQUARE_TYPES = ['router', 'switch', 'wap'] @@ -151,19 +151,19 @@ ICON_DICT = {'router': 'router', 'firewall': 'firewall'} POINTER_JUMP_TO = 0 -POINTER_INFO = 1 -POINTER_GROUP = 2 -POINTER_FILL = 3 +POINTER_INFO = 1 +POINTER_GROUP = 2 +POINTER_FILL = 3 LAYOUT_SYMMETRIC = 0 -LAYOUT_WEIGHTED = 1 +LAYOUT_WEIGHTED = 1 INTERPOLATION_CARTESIAN = 0 -INTERPOLATION_POLAR = 1 +INTERPOLATION_POLAR = 1 FILE_TYPE_PDF = 1 FILE_TYPE_PNG = 2 -FILE_TYPE_PS = 3 +FILE_TYPE_PS = 3 FILE_TYPE_SVG = 4 @@ -189,11 +189,12 @@ class RadialNet(gtk.DrawingArea): self.__interpolation_slow_in_out = True self.__animating = False - self.__animation_rate = 1000 / 60 # 60Hz (human perception factor) + self.__animation_rate = 1000 / 60 # 60Hz (human perception factor) self.__number_of_frames = 60 self.__scale = 1.0 - self.__rotate = 225 # rotated so that single-host traceroute doesn't have overlapping hosts + # rotated so that single-host traceroute doesn't have overlapping hosts + self.__rotate = 225 self.__translation = (0, 0) self.__button1_press = False @@ -251,7 +252,6 @@ class RadialNet(gtk.DrawingArea): self.set_flags(gtk.CAN_FOCUS) self.grab_focus() - def graph_is_not_empty(function): """ Decorator function to prevent the execution when graph not is set @@ -265,7 +265,6 @@ class RadialNet(gtk.DrawingArea): return check_graph_status - def not_is_in_animation(function): """ Decorator function to prevent the execution when graph is animating @@ -279,7 +278,6 @@ class RadialNet(gtk.DrawingArea): return check_animation_status - def save_drawing_to_file(self, file, type=FILE_TYPE_PNG): """ """ @@ -302,7 +300,7 @@ class RadialNet(gtk.DrawingArea): allocation.width, allocation.height) else: - raise TypeError, 'unknown surface type' + raise TypeError('unknown surface type') context = cairo.Context(self.surface) @@ -322,101 +320,85 @@ class RadialNet(gtk.DrawingArea): return True - def get_slow_inout(self): """ """ return self.__interpolation_slow_in_out - def set_slow_inout(self, value): """ """ self.__interpolation_slow_in_out = value - def get_region_color(self): """ """ return self.__region_color - def set_region_color(self, value): """ """ self.__region_color = value - def get_show_region(self): """ """ return self.__show_region - def set_show_region(self, value): """ """ self.__show_region = value self.queue_draw() - def get_pointer_status(self): """ """ return self.__pointer_status - def set_pointer_status(self, pointer_status): """ """ self.__pointer_status = pointer_status - def get_show_address(self): """ """ return self.__show_address - def get_show_hostname(self): """ """ return self.__show_hostname - def get_show_ring(self): """ """ return self.__show_ring - def set_show_address(self, value): """ """ self.__show_address = value self.queue_draw() - def set_show_hostname(self, value): """ """ self.__show_hostname = value self.queue_draw() - def set_show_ring(self, value): """ """ self.__show_ring = value self.queue_draw() - def get_min_ring_gap(self): """ """ return self.__min_ring_gap - @graph_is_not_empty @not_is_in_animation def set_min_ring_gap(self, value): @@ -432,13 +414,11 @@ class RadialNet(gtk.DrawingArea): return True - def get_number_of_frames(self): """ """ return self.__number_of_frames - @not_is_in_animation def set_number_of_frames(self, number_of_frames): """ @@ -451,7 +431,6 @@ class RadialNet(gtk.DrawingArea): self.__number_of_frames = 3 return False - @not_is_in_animation def update_layout(self): """ @@ -462,7 +441,6 @@ class RadialNet(gtk.DrawingArea): self.__calc_interpolation(self.__graph.get_main_node()) self.__livens_up() - @not_is_in_animation def set_layout(self, layout): """ @@ -481,13 +459,11 @@ class RadialNet(gtk.DrawingArea): return False - def get_layout(self): """ """ return self.__layout - @not_is_in_animation def set_interpolation(self, interpolation): """ @@ -496,43 +472,36 @@ class RadialNet(gtk.DrawingArea): return True - def get_interpolation(self): """ """ return self.__interpolation - def get_number_of_rings(self): """ """ return self.__number_of_rings - def get_fisheye_ring(self): """ """ return self.__fisheye_ring - def get_fisheye_interest(self): """ """ return self.__fisheye_interest - def get_fisheye_spread(self): """ """ return self.__fisheye_spread - def get_fisheye(self): """ """ return self.__fisheye - def set_fisheye(self, enable): """ """ @@ -541,7 +510,6 @@ class RadialNet(gtk.DrawingArea): self.__update_nodes_positions() self.queue_draw() - def set_fisheye_ring(self, value): """ """ @@ -551,7 +519,6 @@ class RadialNet(gtk.DrawingArea): self.__update_nodes_positions() self.queue_draw() - def set_fisheye_interest(self, value): """ """ @@ -560,7 +527,6 @@ class RadialNet(gtk.DrawingArea): self.__update_nodes_positions() self.queue_draw() - def set_fisheye_spread(self, value): """ """ @@ -569,45 +535,38 @@ class RadialNet(gtk.DrawingArea): self.__update_nodes_positions() self.queue_draw() - def get_show_icon(self): """ """ return self.__show_icon - def set_show_icon(self, value): """ """ self.__show_icon = value self.queue_draw() - def get_show_latency(self): """ """ return self.__show_latency - def set_show_latency(self, value): """ """ self.__show_latency = value self.queue_draw() - def get_scale(self): """ """ return self.__scale - def get_zoom(self): """ """ return int(round(self.__scale * 100)) - def set_scale(self, scale): """ """ @@ -616,22 +575,19 @@ class RadialNet(gtk.DrawingArea): self.__scale = scale self.queue_draw() - def set_zoom(self, zoom): """ """ if float(zoom) >= 1: - self.set_scale( float(zoom) / 100.0 ) + self.set_scale(float(zoom) / 100.0) self.queue_draw() - def get_ring_gap(self): """ """ return self.__ring_gap - @not_is_in_animation def set_ring_gap(self, ring_gap): """ @@ -642,7 +598,6 @@ class RadialNet(gtk.DrawingArea): self.__update_nodes_positions() self.queue_draw() - def scroll_event(self, widget, event): """ """ @@ -654,7 +609,6 @@ class RadialNet(gtk.DrawingArea): self.queue_draw() - @graph_is_not_empty @not_is_in_animation def key_press(self, widget, event): @@ -678,7 +632,6 @@ class RadialNet(gtk.DrawingArea): return True - @graph_is_not_empty def key_release(self, widget, event): """ @@ -707,7 +660,6 @@ class RadialNet(gtk.DrawingArea): return True - @graph_is_not_empty @not_is_in_animation def enter_notify(self, widget, event): @@ -716,20 +668,18 @@ class RadialNet(gtk.DrawingArea): self.grab_focus() return False - @graph_is_not_empty @not_is_in_animation def leave_notify(self, widget, event): """ """ for node in self.__graph.get_nodes(): - node.set_draw_info({'over':False}) + node.set_draw_info({'over': False}) self.queue_draw() return False - @graph_is_not_empty def button_press(self, widget, event): """ @@ -743,13 +693,15 @@ class RadialNet(gtk.DrawingArea): """ result = self.__get_node_by_coordinate(self.get_pointer()) - if event.button == 1: self.__button1_press = True + if event.button == 1: + self.__button1_press = True # animate if node is pressed if self.__pointer_status == POINTER_JUMP_TO and event.button == 1: # prevent double animation - if self.__animating == True: return False + if self.__animating == True: + return False if result != None: @@ -760,9 +712,9 @@ class RadialNet(gtk.DrawingArea): if node.get_draw_info('group') == True: - node.set_draw_info({'group':False}) - node.set_subtree_info({'grouped':False, - 'group_node':None}) + node.set_draw_info({'group': False}) + node.set_subtree_info({'grouped': False, + 'group_node': None}) self.__animating = True self.__calc_interpolation(node) @@ -772,7 +724,8 @@ class RadialNet(gtk.DrawingArea): elif self.__pointer_status == POINTER_GROUP and event.button == 1: # prevent group on animation - if self.__animating == True: return False + if self.__animating == True: + return False if result != None: @@ -783,17 +736,17 @@ class RadialNet(gtk.DrawingArea): if node.get_draw_info('group') == True: - node.set_draw_info({'group':False}) - node.set_subtree_info({'grouped':False, - 'group_node':None}) + node.set_draw_info({'group': False}) + node.set_subtree_info({'grouped': False, + 'group_node': None}) else: self.__last_group_node = node - node.set_draw_info({'group':True}) - node.set_subtree_info({'grouped':True, - 'group_node':node}) + node.set_draw_info({'group': True}) + node.set_subtree_info({'grouped': True, + 'group_node': node}) self.__animating = True self.__calc_interpolation(self.__graph.get_main_node()) @@ -833,16 +786,17 @@ class RadialNet(gtk.DrawingArea): elif node.get_draw_info('scanned'): view = NodeWindow(node, (int(xw + x), int(yw + y))) + def close_view(view, event, node): view.destroy() del self.__node_views[node] + view.connect("delete-event", close_view, node) view.show_all() self.__node_views[node] = view return False - @graph_is_not_empty def button_release(self, widget, event): """ @@ -867,7 +821,6 @@ class RadialNet(gtk.DrawingArea): return False - @graph_is_not_empty def motion_notify(self, widget, event): """ @@ -883,12 +836,12 @@ class RadialNet(gtk.DrawingArea): pointer = self.get_pointer() for node in self.__graph.get_nodes(): - node.set_draw_info({'over':False}) + node.set_draw_info({'over': False}) result = self.__get_node_by_coordinate(self.get_pointer()) if result != None: - result[0].set_draw_info({'over':True}) + result[0].set_draw_info({'over': True}) elif self.__button1_press == True and self.__last_motion_point != None: @@ -905,7 +858,6 @@ class RadialNet(gtk.DrawingArea): return False - def expose(self, widget, event): """ Drawing callback @@ -928,7 +880,6 @@ class RadialNet(gtk.DrawingArea): return False - @graph_is_not_empty def __draw(self, context): """ @@ -1000,15 +951,19 @@ class RadialNet(gtk.DrawingArea): context.set_source_rgb(r, g, b) context.set_line_width(1) - xa, ya = PolarCoordinate(i_radius, final).to_cartesian() - xb, yb = PolarCoordinate(f_radius, final).to_cartesian() + xa, ya = PolarCoordinate( + i_radius, final).to_cartesian() + xb, yb = PolarCoordinate( + f_radius, final).to_cartesian() context.move_to(xc + xa, yc - ya) context.line_to(xc + xb, yc - yb) context.stroke() - xa, ya = PolarCoordinate(i_radius, start).to_cartesian() - xb, yb = PolarCoordinate(f_radius, start).to_cartesian() + xa, ya = PolarCoordinate( + i_radius, start).to_cartesian() + xb, yb = PolarCoordinate( + f_radius, start).to_cartesian() context.move_to(xc + xa, yc - ya) context.line_to(xc + xb, yc - yb) @@ -1052,7 +1007,8 @@ class RadialNet(gtk.DrawingArea): elif not a_is_grouped or not b_is_grouped: - if not (a_is_group and b_is_child or b_is_group and a_is_child): + if not (a_is_group and b_is_child or + b_is_group and a_is_child): self.__draw_edge(context, edge) elif a_group != b_group: @@ -1067,7 +1023,6 @@ class RadialNet(gtk.DrawingArea): if group == self.__last_group_node or not grouped: self.__draw_node(context, node) - def __draw_edge(self, context, edge): """ Draw the connection between two nodes @@ -1131,7 +1086,6 @@ class RadialNet(gtk.DrawingArea): context.show_text(str(round(latency, 2))) context.stroke() - def __draw_node(self, context, node): """ Draw nodes and your informations @@ -1263,21 +1217,18 @@ class RadialNet(gtk.DrawingArea): context.set_line_width(1) context.stroke() - def __check_fisheye_ring(self): """ """ if self.__fisheye_ring >= self.__number_of_rings: self.__fisheye_ring = self.__number_of_rings - 1 - def __set_number_of_rings(self, value): """ """ self.__number_of_rings = value self.__check_fisheye_ring() - def __fisheye_function(self, ring): """ """ @@ -1292,7 +1243,6 @@ class RadialNet(gtk.DrawingArea): return value - @graph_is_not_empty @not_is_in_animation def __update_nodes_positions(self): @@ -1315,7 +1265,6 @@ class RadialNet(gtk.DrawingArea): ring = node.get_draw_info('ring') node.set_coordinate_radius(self.__calc_radius(ring)) - @graph_is_not_empty def __get_node_by_coordinate(self, point): """ @@ -1345,7 +1294,6 @@ class RadialNet(gtk.DrawingArea): return None - def __calc_radius(self, ring): """ """ @@ -1363,7 +1311,6 @@ class RadialNet(gtk.DrawingArea): return radius - @graph_is_not_empty def __arrange_nodes(self): """ @@ -1385,10 +1332,11 @@ class RadialNet(gtk.DrawingArea): old_nodes.add(node) # set ring location - node.set_draw_info({'ring':ring}) + node.set_draw_info({'ring': ring}) # check group constraints - if node.get_draw_info('group') or node.get_draw_info('grouped'): + if (node.get_draw_info('group') or + node.get_draw_info('grouped')): children = node.get_draw_info('children') else: @@ -1404,9 +1352,10 @@ class RadialNet(gtk.DrawingArea): # setting father foreign for child in children: - child.set_draw_info({'father':node}) + child.set_draw_info({'father': node}) - node.set_draw_info({'children':misc.sort_children(children, node)}) + node.set_draw_info( + {'children': misc.sort_children(children, node)}) tmp_nodes.update(children) # check group influence in number of rings @@ -1425,12 +1374,11 @@ class RadialNet(gtk.DrawingArea): self.__set_number_of_rings(number_of_needed_rings) - def __weighted_layout(self): """ """ # calculating the space needed by each node - self.__graph.get_main_node().set_draw_info({'range':(0, 360)}) + self.__graph.get_main_node().set_draw_info({'range': (0, 360)}) new_nodes = set([self.__graph.get_main_node()]) self.__graph.get_main_node().calc_needed_space() @@ -1462,15 +1410,14 @@ class RadialNet(gtk.DrawingArea): theta = child_total / 2 + min + self.__rotate child.set_coordinate_theta(theta) - child.set_draw_info({'range':(min, min + child_total)}) + child.set_draw_info({'range': (min, min + child_total)}) min += child_total - def __symmetric_layout(self): """ """ - self.__graph.get_main_node().set_draw_info({'range':(0, 360)}) + self.__graph.get_main_node().set_draw_info({'range': (0, 360)}) new_nodes = set([self.__graph.get_main_node()]) while len(new_nodes) > 0: @@ -1495,11 +1442,10 @@ class RadialNet(gtk.DrawingArea): theta = factor / 2 + min + self.__rotate child.set_coordinate_theta(theta) - child.set_draw_info({'range':(min, min + factor)}) + child.set_draw_info({'range': (min, min + factor)}) min += factor - @graph_is_not_empty def __calc_layout(self, reference): """ @@ -1524,8 +1470,7 @@ class RadialNet(gtk.DrawingArea): node.set_coordinate_theta(theta - factor) a, b = node.get_draw_info('range') - node.set_draw_info({'range':(a - factor, b - factor)}) - + node.set_draw_info({'range': (a - factor, b - factor)}) @graph_is_not_empty def __calc_node_positions(self, reference=None): @@ -1544,7 +1489,6 @@ class RadialNet(gtk.DrawingArea): # set nodes' coordinate theta self.__calc_layout(reference) - def __calc_interpolation(self, focus): """ """ @@ -1560,7 +1504,7 @@ class RadialNet(gtk.DrawingArea): elif self.__interpolation == INTERPOLATION_CARTESIAN: coordinate = node.get_cartesian_coordinate() - node.set_draw_info({'start_coordinate':coordinate}) + node.set_draw_info({'start_coordinate': coordinate}) father = focus.get_draw_info('father') @@ -1605,7 +1549,7 @@ class RadialNet(gtk.DrawingArea): if self.__interpolation == INTERPOLATION_POLAR: coordinate = node.get_polar_coordinate() - node.set_draw_info({'final_coordinate':coordinate}) + node.set_draw_info({'final_coordinate': coordinate}) # adjusting polar coordinates ri, ti = node.get_draw_info('start_coordinate') @@ -1619,18 +1563,20 @@ class RadialNet(gtk.DrawingArea): ti, tf = geometry.calculate_short_path(ti, tf) # main node goes direct to center (no arc) - if node == self.__graph.get_main_node(): tf = ti + if node == self.__graph.get_main_node(): + tf = ti # old main node goes direct to new position (no arc) - if node == old_main_node: ti = tf + if node == old_main_node: + ti = tf - node.set_draw_info({'start_coordinate':(ri, ti)}) - node.set_draw_info({'final_coordinate':(rf, tf)}) + node.set_draw_info({'start_coordinate': (ri, ti)}) + node.set_draw_info({'final_coordinate': (rf, tf)}) elif self.__interpolation == INTERPOLATION_CARTESIAN: coordinate = node.get_cartesian_coordinate() - node.set_draw_info({'final_coordinate':coordinate}) + node.set_draw_info({'final_coordinate': coordinate}) # calculate interpolated points ai, bi = node.get_draw_info('start_coordinate') @@ -1640,16 +1586,16 @@ class RadialNet(gtk.DrawingArea): l2di.set_final_point(af, bf) if self.__interpolation_slow_in_out: - points = l2di.get_weighed_points(self.__number_of_frames, steps) + points = l2di.get_weighed_points( + self.__number_of_frames, steps) else: points = l2di.get_points(self.__number_of_frames) - node.set_draw_info({'interpolated_coordinate':points}) + node.set_draw_info({'interpolated_coordinate': points}) return True - def __livens_up(self, index=0): """ """ @@ -1696,16 +1642,15 @@ class RadialNet(gtk.DrawingArea): # animation continue condition if index < self.__number_of_frames - 1: - gobject.timeout_add(self.__animation_rate, # time to recall - self.__livens_up, # recursive call - index + 1) # next iteration + gobject.timeout_add(self.__animation_rate, # time to recall + self.__livens_up, # recursive call + index + 1) # next iteration else: self.__last_group_node = None self.__animating = False return False - @not_is_in_animation def set_graph(self, graph): """ @@ -1723,7 +1668,6 @@ class RadialNet(gtk.DrawingArea): else: self.__graph = None - def get_scanned_nodes(self): """ """ @@ -1738,13 +1682,11 @@ class RadialNet(gtk.DrawingArea): return nodes - def get_graph(self): """ """ return self.__graph - def set_empty(self): """ """ @@ -1753,13 +1695,11 @@ class RadialNet(gtk.DrawingArea): self.queue_draw() - def get_rotation(self): """ """ return self.__rotate - @graph_is_not_empty def set_rotation(self, angle): """ @@ -1774,13 +1714,11 @@ class RadialNet(gtk.DrawingArea): self.queue_draw() - def get_translation(self): """ """ return self.__translation - @graph_is_not_empty def set_translation(self, translation): """ @@ -1788,7 +1726,6 @@ class RadialNet(gtk.DrawingArea): self.__translation = translation self.queue_draw() - def is_empty(self): """ """ @@ -1797,19 +1734,16 @@ class RadialNet(gtk.DrawingArea): return False - def is_in_animation(self): """ """ return self.__animating - def calc_sorted_nodes(self): """ """ self.__sorted_nodes = list(self.__graph.get_nodes()) - self.__sorted_nodes.sort(key = lambda n: n.get_draw_info('ring')) - + self.__sorted_nodes.sort(key=lambda n: n.get_draw_info('ring')) class NetNode(Node): @@ -1825,21 +1759,18 @@ class NetNode(Node): super(NetNode, self).__init__() - def get_host(self): """ Set the HostInfo that this node represents """ return self.get_data() - def set_host(self, host): """ Set the HostInfo that this node represents """ self.set_data(host) - def get_info(self, info): """Return various information extracted from the host set with set_host.""" @@ -1910,7 +1841,6 @@ class NetNode(Node): os_class["type"] = osclass.get("type", "") os_class["vendor"] = osclass.get("vendor", "") - #os_class["accuracy"] = int(osclass.get("accuracy", "")) os_class["accuracy"] = osclass.get("accuracy", "") os_class["os_family"] = osclass.get("osfamily", "") os_class["os_gen"] = osclass.get("osgen", "") @@ -1941,30 +1871,38 @@ class NetNode(Node): elif info == "sequences": # getting sequences information sequences = {} - # If all fields are empty, we don't put it into the sequences list - if reduce(lambda x,y: x + y, host.tcpsequence.values(), "") != "": + # If all fields are empty, we don't put it into the sequences + # list + if reduce(lambda x, y: x + y, + host.tcpsequence.values(), "") != "": tcp = {} if host.tcpsequence.get("index", "") != "": tcp["index"] = int(host.tcpsequence["index"]) else: tcp["index"] = 0 tcp["class"] = "" # not supported - tcp["values"] = host.tcpsequence.get("values", "").split(",") + tcp["values"] = host.tcpsequence.get( + "values", "").split(",") tcp["difficulty"] = host.tcpsequence.get("difficulty", "") sequences["tcp"] = tcp - if reduce(lambda x,y: x + y, host.ipidsequence.values(), "") != "": + if reduce(lambda x, y: x + y, + host.ipidsequence.values(), "") != "": ip_id = {} ip_id["class"] = host.ipidsequence.get("class", "") - ip_id["values"] = host.ipidsequence.get("values", "").split(",") + ip_id["values"] = host.ipidsequence.get( + "values", "").split(",") sequences["ip_id"] = ip_id - if reduce(lambda x,y: x + y, host.tcptssequence.values(), "") != "": + if reduce(lambda x, y: x + y, + host.tcptssequence.values(), "") != "": tcp_ts = {} tcp_ts["class"] = host.tcptssequence.get("class", "") - tcp_ts["values"] = host.tcptssequence.get("values", "").split(",") + tcp_ts["values"] = host.tcptssequence.get( + "values", "").split(",") sequences["tcp_ts"] = tcp_ts return sequences elif info == "filtered": - if len(host.extraports) > 0 and host.extraports[0]["state"] == "filtered": + if (len(host.extraports) > 0 and + host.extraports[0]["state"] == "filtered"): return True else: for port in host.ports: @@ -1992,7 +1930,8 @@ class NetNode(Node): service["method"] = host_port.get("service_method", "") service["version"] = host_port.get("service_version", "") service["product"] = host_port.get("service_product", "") - service["extrainfo"] = host_port.get("service_extrainfo", "") + service["extrainfo"] = host_port.get( + "service_extrainfo", "") port["state"] = state port["scripts"] = None # not supported @@ -2032,36 +1971,31 @@ class NetNode(Node): trace["protocol"] = host.trace.get("proto", "") return trace - else: # host is None + else: # host is None pass return None - def get_coordinate_theta(self): """ """ return self.__coordinate.get_theta() - def get_coordinate_radius(self): """ """ return self.__coordinate.get_radius() - def set_coordinate_theta(self, value): """ """ self.__coordinate.set_theta(value) - def set_coordinate_radius(self, value): """ """ self.__coordinate.set_radius(value) - def set_polar_coordinate(self, r, t): """ Set polar coordinate @@ -2072,7 +2006,6 @@ class NetNode(Node): """ self.__coordinate.set_coordinate(r, t) - def get_polar_coordinate(self): """ Get cartesian coordinate @@ -2081,7 +2014,6 @@ class NetNode(Node): """ return self.__coordinate.get_coordinate() - def set_cartesian_coordinate(self, x, y): """ Set cartesian coordinate @@ -2091,7 +2023,6 @@ class NetNode(Node): self.set_polar_coordinate(r, math.degrees(t)) - def get_cartesian_coordinate(self): """ Get cartesian coordinate @@ -2100,7 +2031,6 @@ class NetNode(Node): """ return self.__coordinate.to_cartesian() - def get_draw_info(self, info=None): """ Get draw information about node @@ -2112,12 +2042,11 @@ class NetNode(Node): if info == None: return self.__draw_info - if self.__draw_info.has_key(info): + if info in self.__draw_info: return self.__draw_info[info] return None - def set_draw_info(self, info): """ Set draw information @@ -2127,7 +2056,6 @@ class NetNode(Node): for key in info: self.__draw_info[key] = info[key] - def deep_search_child(self, node): """ """ @@ -2141,7 +2069,6 @@ class NetNode(Node): return False - def set_subtree_info(self, info): """ """ @@ -2152,7 +2079,6 @@ class NetNode(Node): if child.get_draw_info('group') != True: child.set_subtree_info(info) - def calc_needed_space(self): """ """ @@ -2172,6 +2098,5 @@ class NetNode(Node): size = self.get_draw_info('radius') * 2 own_angle = geometry.angle_from_object(distance, size) - self.set_draw_info({'children_need':sum_angle}) - self.set_draw_info({'space_need':max(sum_angle, own_angle)}) - + self.set_draw_info({'children_need': sum_angle}) + self.set_draw_info({'space_need': max(sum_angle, own_angle)}) diff --git a/zenmap/radialnet/gui/SaveDialog.py b/zenmap/radialnet/gui/SaveDialog.py index d9de1e6d6..a5b0d0eba 100644 --- a/zenmap/radialnet/gui/SaveDialog.py +++ b/zenmap/radialnet/gui/SaveDialog.py @@ -133,8 +133,8 @@ TYPES = ((_("By extension"), None, None), (_("PNG"), RadialNet.FILE_TYPE_PNG, ".png"), (_("PostScript"), RadialNet.FILE_TYPE_PS, ".ps"), (_("SVG"), RadialNet.FILE_TYPE_SVG, ".svg")) -# Build a reverse index of extensions to file types, for the "By extension" file -# type. +# Build a reverse index of extensions to file types, for the "By extension" +# file type. EXTENSIONS = {} for type in TYPES: if type[2] is not None: @@ -181,7 +181,8 @@ class SaveDialog(zenmapGUI.FileChoosers.UnicodeFileChooserDialog): self.set_current_folder(dir) # Find the recommended extension. - new_ext = self.__combo.get_model().get_value(self.__combo.get_active_iter(), 2) + new_ext = self.__combo.get_model().get_value( + self.__combo.get_active_iter(), 2) if new_ext is not None: # Change the filename to use the recommended extension. root, ext = os.path.splitext(basename) @@ -197,15 +198,17 @@ class SaveDialog(zenmapGUI.FileChoosers.UnicodeFileChooserDialog): if ext == "": filename = self.get_filename() or "" dir, basename = os.path.split(filename) - alert = HIGAlertDialog(message_format=_("No filename extension"), - secondary_text=_("""\ -The filename "%s" does not have an extension, and no specific file type was chosen. -Enter a known extension or select the file type from the list.\ -""" % basename)) + alert = HIGAlertDialog( + message_format=_("No filename extension"), + secondary_text=_("""\ +The filename "%s" does not have an extension, \ +and no specific file type was chosen. +Enter a known extension or select the file type from the list.""" % basename)) else: - alert = HIGAlertDialog(message_format=_("Unknown filename extension"), - secondary_text=_("""\ + alert = HIGAlertDialog( + message_format=_("Unknown filename extension"), + secondary_text=_("""\ There is no file type known for the filename extension "%s". Enter a known extension or select the file type from the list.\ """) % self.__get_extension()) @@ -218,7 +221,8 @@ Enter a known extension or select the file type from the list.\ return os.path.splitext(self.get_filename())[1] def get_filetype(self): - 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. return EXTENSIONS.get(self.__get_extension()) diff --git a/zenmap/radialnet/gui/Toolbar.py b/zenmap/radialnet/gui/Toolbar.py index 391767292..bb419d8fb 100644 --- a/zenmap/radialnet/gui/Toolbar.py +++ b/zenmap/radialnet/gui/Toolbar.py @@ -136,7 +136,6 @@ HIDE = False REFRESH_RATE = 500 - class ToolsMenu(gtk.Menu): """ """ @@ -149,7 +148,6 @@ class ToolsMenu(gtk.Menu): self.__create_items() - def __create_items(self): """ """ @@ -163,7 +161,6 @@ class ToolsMenu(gtk.Menu): self.__hosts.show_all() - def __hosts_viewer_callback(self, widget): """ """ @@ -171,20 +168,17 @@ class ToolsMenu(gtk.Menu): window.show_all() window.set_keep_above(True) - def enable_dependents(self): """ """ self.__hosts.set_sensitive(True) - def disable_dependents(self): """ """ self.__hosts.set_sensitive(False) - class Toolbar(gtk.HBox): """ """ @@ -213,7 +207,6 @@ class Toolbar(gtk.HBox): self.__create_widgets() - def __create_widgets(self): """ """ @@ -233,7 +226,8 @@ class Toolbar(gtk.HBox): self.__hosts_button = BWStockButton(gtk.STOCK_INDEX, _("Hosts Viewer")) self.__hosts_button.connect("clicked", self.__hosts_viewer_callback) - self.__control = BWToggleStockButton(gtk.STOCK_PROPERTIES, _("Controls")) + self.__control = BWToggleStockButton( + gtk.STOCK_PROPERTIES, _("Controls")) self.__control.connect('clicked', self.__control_callback) self.__control.set_active(False) @@ -273,7 +267,6 @@ class Toolbar(gtk.HBox): self.pack_start(self.__control, False) self.pack_end(self.__save_button, False) - def disable_controls(self): """ """ @@ -282,7 +275,6 @@ class Toolbar(gtk.HBox): self.__hosts_button.set_sensitive(False) #self.__tools_menu.disable_dependents() - def enable_controls(self): """ """ @@ -291,13 +283,11 @@ class Toolbar(gtk.HBox): self.__hosts_button.set_sensitive(True) #self.__tools_menu.enable_dependents() - def __tools_callback(self, widget): """ """ self.__tools_menu.popup(None, None, None, 1, 0) - def __hosts_viewer_callback(self, widget): """ """ @@ -305,7 +295,6 @@ class Toolbar(gtk.HBox): window.show_all() window.set_keep_above(True) - def __save_image_callback(self, widget): """ """ @@ -330,7 +319,6 @@ class Toolbar(gtk.HBox): self.__save_chooser.hide() - def __control_callback(self, widget=None): """ """ @@ -340,7 +328,6 @@ class Toolbar(gtk.HBox): else: self.__control_widget.hide() - def __fisheye_callback(self, widget=None): """ """ @@ -356,14 +343,12 @@ class Toolbar(gtk.HBox): self.__fisheye_widget.deactive_fisheye() self.__fisheye_widget.hide() - def __about_callback(self, widget): """ """ self.__about_dialog = AboutDialog() self.__about_dialog.show_all() - def __fullscreen_callback(self, widget=None): """ """ @@ -372,4 +357,3 @@ class Toolbar(gtk.HBox): else: self.__window.unfullscreen() - diff --git a/zenmap/radialnet/gui/__init__.py b/zenmap/radialnet/gui/__init__.py index 9c388f149..fb166b3fb 100644 --- a/zenmap/radialnet/gui/__init__.py +++ b/zenmap/radialnet/gui/__init__.py @@ -118,4 +118,3 @@ # * Nmap, and also available from https://svn.nmap.org/nmap/COPYING * # * * # ***************************************************************************/ - diff --git a/zenmap/radialnet/util/__init__.py b/zenmap/radialnet/util/__init__.py index 9c388f149..fb166b3fb 100644 --- a/zenmap/radialnet/util/__init__.py +++ b/zenmap/radialnet/util/__init__.py @@ -118,4 +118,3 @@ # * Nmap, and also available from https://svn.nmap.org/nmap/COPYING * # * * # ***************************************************************************/ - diff --git a/zenmap/radialnet/util/geometry.py b/zenmap/radialnet/util/geometry.py index efcad82a5..c5c815044 100644 --- a/zenmap/radialnet/util/geometry.py +++ b/zenmap/radialnet/util/geometry.py @@ -141,7 +141,7 @@ def is_in_circle(point, radius=1, center=(0, 0)): x, y = point a, b = center - if ((x - a)**2 + (y - b)**2) <= (radius**2): + if ((x - a) ** 2 + (y - b) ** 2) <= (radius ** 2): return True return False diff --git a/zenmap/radialnet/util/integration.py b/zenmap/radialnet/util/integration.py index c420b5f91..8a1c4a39b 100644 --- a/zenmap/radialnet/util/integration.py +++ b/zenmap/radialnet/util/integration.py @@ -135,16 +135,17 @@ BASE_RADIUS = 5.5 NONE_RADIUS = 4.5 - def set_node_info(node, host): """ """ node.set_host(host) - radius = BASE_RADIUS + 2 * math.log(node.get_info("number_of_open_ports") + 1) + radius = BASE_RADIUS + 2 * math.log( + node.get_info("number_of_open_ports") + 1) + + node.set_draw_info({"color": COLORS[node.get_info("vulnerability_score")], + "radius": radius}) - node.set_draw_info({"color":COLORS[node.get_info("vulnerability_score")], - "radius":radius}) class TracerouteHostInfo(object): """This is a minimal implementation of HostInfo, sufficient to @@ -164,15 +165,18 @@ class TracerouteHostInfo(object): def get_best_osmatch(self): if not self.osmatches: return None + def osmatch_key(osmatch): try: return -float(osmatch["accuracy"]) except ValueError: return 0 - return sorted(self.osmatches, key = osmatch_key)[0] + + return sorted(self.osmatches, key=osmatch_key)[0] hostnames = property(lambda self: self.hostname and [self.hostname] or []) + def make_graph_from_hosts(hosts): #hosts = parser.get_root().search_children('host', deep=True) graph = Graph() @@ -187,7 +191,8 @@ def make_graph_from_hosts(hosts): localhost.ip = {"addr": "127.0.0.1/8", "type": "ipv4"} localhost.hostname = "localhost" main_node.set_host(localhost) - main_node.set_draw_info({"valid": True, "color":(0,0,0), "radius":NONE_RADIUS}) + main_node.set_draw_info( + {"valid": True, "color": (0, 0, 0), "radius": NONE_RADIUS}) #Save endpoints for attaching scanned hosts to endpoints = {} @@ -219,10 +224,14 @@ def make_graph_from_hosts(hosts): nodes.append(node) hop_host = TracerouteHostInfo() - hop_host.ip = {"addr": hop["ipaddr"], "type": "", "vendor": ""} - node.set_draw_info({"valid":True}) - node.set_draw_info({"color":(1,1,1), - "radius":NONE_RADIUS}) + hop_host.ip = { + "addr": hop["ipaddr"], + "type": "", + "vendor": "" + } + node.set_draw_info({"valid": True}) + node.set_draw_info({"color": (1, 1, 1), + "radius": NONE_RADIUS}) if hop["host"] != "": hop_host.hostname = hop["host"] @@ -240,8 +249,9 @@ def make_graph_from_hosts(hosts): node = NetNode() nodes.append(node) - node.set_draw_info({"valid":False}) - node.set_draw_info({"color":(1,1,1), "radius":NONE_RADIUS}) + node.set_draw_info({"valid": False}) + node.set_draw_info( + {"color": (1, 1, 1), "radius": NONE_RADIUS}) graph.set_connection(node, prev_node) @@ -259,12 +269,12 @@ def make_graph_from_hosts(hosts): node = NetNode() nodes.append(node) - node.set_draw_info({"no_route":True}) + node.set_draw_info({"no_route": True}) graph.set_connection(node, endpoints[host]) - node.set_draw_info({"valid":True}) - node.set_draw_info({"scanned":True}) + node.set_draw_info({"valid": True}) + node.set_draw_info({"scanned": True}) set_node_info(node, host) node_cache[node.get_info("ip")] = node diff --git a/zenmap/radialnet/util/misc.py b/zenmap/radialnet/util/misc.py index ea0abdb49..631972968 100644 --- a/zenmap/radialnet/util/misc.py +++ b/zenmap/radialnet/util/misc.py @@ -124,7 +124,6 @@ from radialnet.util.geometry import * import math - def ipv4_compare(ip1, ip2): """ """ @@ -174,5 +173,7 @@ def sort_children_by_angle(children): """ vector = list(children) - vector.sort(key = lambda c: normalize_angle(c.get_draw_info('angle_from_father'))) + vector.sort( + key=lambda c: normalize_angle( + c.get_draw_info('angle_from_father'))) return vector diff --git a/zenmap/setup.py b/zenmap/setup.py index fb041a2a8..0bc9f06d0 100755 --- a/zenmap/setup.py +++ b/zenmap/setup.py @@ -135,7 +135,8 @@ from glob import glob from stat import * from zenmapCore.Version import VERSION -from zenmapCore.Name import APP_NAME, APP_DISPLAY_NAME, APP_WEB_SITE, APP_DOWNLOAD_SITE, NMAP_DISPLAY_NAME +from zenmapCore.Name import APP_NAME, APP_DISPLAY_NAME, APP_WEB_SITE,\ + APP_DOWNLOAD_SITE, NMAP_DISPLAY_NAME # The name of the file used to record the list of installed files, so that the # uninstall command can remove them. @@ -154,6 +155,7 @@ misc_dir = os.path.join(data_dir, 'misc') # Where to install .desktop files. desktop_dir = os.path.join('share', 'applications') + def mo_find(result, dirname, fnames): files = [] for f in fnames: @@ -164,29 +166,31 @@ def mo_find(result, dirname, fnames): if files: result.append((dirname, files)) -################################################################################ +############################################################################### # Installation variables -data_files = [ (pixmaps_dir, glob(os.path.join(pixmaps_dir, '*.gif')) + - glob(os.path.join(pixmaps_dir, '*.png'))), +data_files = [ + (pixmaps_dir, glob(os.path.join(pixmaps_dir, '*.gif')) + + glob(os.path.join(pixmaps_dir, '*.png'))), - (os.path.join(pixmaps_dir, "radialnet"), - glob(os.path.join(pixmaps_dir, "radialnet", '*.png'))), + (os.path.join(pixmaps_dir, "radialnet"), + glob(os.path.join(pixmaps_dir, "radialnet", '*.png'))), - (config_dir, [os.path.join(config_dir, APP_NAME + '.conf')] + - [os.path.join(config_dir, 'scan_profile.usp')] + - [os.path.join(config_dir, APP_NAME + '_version')]), + (config_dir, [os.path.join(config_dir, APP_NAME + '.conf'), + os.path.join(config_dir, 'scan_profile.usp'), + os.path.join(config_dir, APP_NAME + '_version')]), - (misc_dir, glob(os.path.join(misc_dir, '*.xml'))), + (misc_dir, glob(os.path.join(misc_dir, '*.xml'))), - (docs_dir, [os.path.join(docs_dir, 'help.html')])] + (docs_dir, [os.path.join(docs_dir, 'help.html')]) + ] # Add i18n files to data_files list os.path.walk(locale_dir, mo_find, data_files) + # path_startswith and path_strip_prefix are used to deal with the installation # root (--root option, also known as DESTDIR). - def path_startswith(path, prefix): """Returns True if path starts with prefix. It's a little more intelligent than str.startswith because it normalizes the paths to remove multiple @@ -195,10 +199,11 @@ def path_startswith(path, prefix): prefix = os.path.normpath(prefix) return path.startswith(prefix) + def path_strip_prefix(path, prefix): """Return path stripped of its directory prefix if it starts with prefix, - otherwise return path unmodified. This only works correctly with Unix paths; - for example it will not replace the drive letter on a Windows path. + otherwise return path unmodified. This only works correctly with Unix + paths; for example it will not replace the drive letter on a Windows path. Examples: >>> path_strip_prefix('/tmp/destdir/usr/bin', '/tmp/destdir') '/usr/bin' @@ -221,14 +226,16 @@ def path_strip_prefix(path, prefix): assert os.path.isabs(path) == absolute return path -################################################################################ +############################################################################### # Distutils subclasses + class my_install(install): def finalize_options(self): # Ubuntu's python2.6-2.6.4-0ubuntu3 package changes sys.prefix in # install.finalize_options when sys.prefix is "/usr/local" (our - # default). Because we need the unchanged value later, remember it here. + # default). Because we need the unchanged value later, remember it + # here. self.saved_prefix = self.prefix install.finalize_options(self) @@ -252,14 +259,17 @@ class my_install(install): # Recursively include all the directories in data_dir (share/zenmap). # This is mainly for convenience in listing locale directories. installed_files.append(os.path.join(self.install_data, data_dir)) - for dirpath, dirs, files in os.walk(os.path.join(self.install_data, data_dir)): + for dirpath, dirs, files in os.walk( + os.path.join(self.install_data, data_dir)): for dir in dirs: installed_files.append(os.path.join(dirpath, dir)) - installed_files.append(os.path.join(self.install_scripts, "uninstall_" + APP_NAME)) + installed_files.append( + os.path.join(self.install_scripts, "uninstall_" + APP_NAME)) return installed_files def create_uninstaller(self): - uninstaller_filename = os.path.join(self.install_scripts, "uninstall_" + APP_NAME) + uninstaller_filename = os.path.join( + self.install_scripts, "uninstall_" + APP_NAME) uninstaller = """\ #!/usr/bin/env python @@ -267,26 +277,28 @@ import errno, os, os.path, sys print 'Uninstall %(name)s %(version)s' -answer = raw_input('Are you sure that you want to uninstall %(name)s %(version)s? (yes/no) ') +answer = raw_input('Are you sure that you want to uninstall ' + '%(name)s %(version)s? (yes/no) ') if answer != 'yes' and answer != 'y': print 'Not uninstalling.' sys.exit(0) -""" % {'name':APP_DISPLAY_NAME, 'version':VERSION} +""" % {'name': APP_DISPLAY_NAME, 'version': VERSION} installed_files = [] for output in self.get_installed_files(): if self.root is not None: - # If we have a root (DESTDIR), we need to strip it off the front - # of paths so the uninstaller runs on the target host. The path - # manipulations are tricky, but made easier because the - # uninstaller only has to run on Unix. + # If we have a root (DESTDIR), we need to strip it off the + # front of paths so the uninstaller runs on the target host. + # The path manipulations are tricky, but made easier because + # the uninstaller only has to run on Unix. if not path_startswith(output, self.root): - # This should never happen (everything gets installed inside - # the root), but if it does, be safe and don't delete - # anything. - uninstaller += "print '%s was not installed inside the root %s; skipping.'\n" % (output, self.root) + # This should never happen (everything gets installed + # inside the root), but if it does, be safe and don't + # delete anything. + uninstaller += ("print '%s was not installed inside " + "the root %s; skipping.'\n" % (output, self.root)) continue output = path_strip_prefix(output, self.root) assert os.path.isabs(output) @@ -356,7 +368,8 @@ for dir in dirs: lines[i] = "INSTALL_LIB = %s\n" % repr(modules_dir) break else: - raise ValueError("INSTALL_LIB replacement not found in %s" % app_file_name) + raise ValueError( + "INSTALL_LIB replacement not found in %s" % app_file_name) app_file = open(app_file_name, "w") app_file.writelines(lines) @@ -380,16 +393,17 @@ for dir in dirs: S_IRGRP | \ S_IROTH) - def fix_paths(self): """Replace some hardcoded paths to match where files were installed.""" - interesting_paths = {"CONFIG_DIR": os.path.join(self.saved_prefix, config_dir), - "DOCS_DIR": os.path.join(self.saved_prefix, docs_dir), - "LOCALE_DIR": os.path.join(self.saved_prefix, locale_dir), - "MISC_DIR": os.path.join(self.saved_prefix, misc_dir), - "PIXMAPS_DIR": os.path.join(self.saved_prefix, pixmaps_dir), - # See $(nmapdatadir) in nmap/Makefile.in. - "NMAPDATADIR": os.path.join(self.saved_prefix, "share", "nmap"),} + interesting_paths = { + "CONFIG_DIR": os.path.join(self.saved_prefix, config_dir), + "DOCS_DIR": os.path.join(self.saved_prefix, docs_dir), + "LOCALE_DIR": os.path.join(self.saved_prefix, locale_dir), + "MISC_DIR": os.path.join(self.saved_prefix, misc_dir), + "PIXMAPS_DIR": os.path.join(self.saved_prefix, pixmaps_dir), + # See $(nmapdatadir) in nmap/Makefile.in. + "NMAPDATADIR": os.path.join(self.saved_prefix, "share", "nmap") + } # Find and read the Paths.py file. pcontent = "" @@ -417,8 +431,10 @@ for dir in dirs: # Rewrite the zenmap.desktop and zenmap-root.desktop files to point to # the installed locations of the su-to-zenmap.sh script and application # icon. - su_filename = os.path.join(self.saved_prefix, data_dir, "su-to-zenmap.sh") - icon_filename = os.path.join(self.saved_prefix, pixmaps_dir, "zenmap.png") + su_filename = os.path.join( + self.saved_prefix, data_dir, "su-to-zenmap.sh") + icon_filename = os.path.join( + self.saved_prefix, pixmaps_dir, "zenmap.png") desktop_filename = None root_desktop_filename = None @@ -442,7 +458,9 @@ for dir in dirs: df = open(root_desktop_filename, "r") dcontent = df.read() df.close() - regex = re.compile("^((?:Exec|TryExec) *= *).*su-to-zenmap.sh(.*)$", re.MULTILINE) + regex = re.compile( + "^((?:Exec|TryExec) *= *).*su-to-zenmap.sh(.*)$", + re.MULTILINE) dcontent = regex.sub("\\1%s\\2" % su_filename, dcontent) regex = re.compile("^(Icon *= *).*$", re.MULTILINE) dcontent = regex.sub("\\1%s" % icon_filename, dcontent) @@ -456,7 +474,8 @@ for dir in dirs: doesn't strip off the installation root, if any. File names containing newline characters are not handled.""" if INSTALLED_FILES_NAME == self.record: - distutils.log.warn("warning: installation record is overwriting --record file '%s'." % self.record) + distutils.log.warn("warning: installation record is overwriting " + "--record file '%s'." % self.record) f = open(INSTALLED_FILES_NAME, "w") try: for output in self.get_installed_files(): @@ -465,12 +484,14 @@ for dir in dirs: finally: f.close() + class my_uninstall(Command): """A distutils command that performs uninstallation. It reads the list of installed files written by the install command.""" command_name = "uninstall" - description = "uninstall installed files recorded in '%s'" % INSTALLED_FILES_NAME + description = "uninstall installed files recorded in '%s'" % ( + INSTALLED_FILES_NAME) user_options = [] def initialize_options(self): @@ -485,7 +506,8 @@ class my_uninstall(Command): f = open(INSTALLED_FILES_NAME, "r") except IOError, e: if e.errno == errno.ENOENT: - log.error("Couldn't open the installation record '%s'. Have you installed yet?" % INSTALLED_FILES_NAME) + log.error("Couldn't open the installation record '%s'. " + "Have you installed yet?" % INSTALLED_FILES_NAME) return installed_files = [file.rstrip("\n") for file in f.readlines()] f.close() @@ -510,7 +532,7 @@ class my_uninstall(Command): # Delete the directories. First reverse-sort the normalized paths by # length so that child directories are deleted before their parents. dirs = [os.path.normpath(dir) for dir in dirs] - dirs.sort(key = len, reverse = True) + dirs.sort(key=len, reverse=True) for dir in dirs: try: log.info("Removing the directory '%s'." % dir) @@ -523,8 +545,8 @@ class my_uninstall(Command): log.error(str(e)) # setup can be called in different ways depending on what we're doing. (For -# example py2exe needs special handling.) These arguments are common between all -# the operations. +# example py2exe needs special handling.) These arguments are common between +# all the operations. COMMON_SETUP_ARGS = { 'name': APP_NAME, 'license': 'Nmap License (http://nmap.org/book/man-legal.html)', @@ -533,14 +555,14 @@ COMMON_SETUP_ARGS = { 'author': 'Nmap Project', 'maintainer': 'Nmap Project', 'description': "%s frontend and results viewer" % NMAP_DISPLAY_NAME, - 'long_description': """\ -%s is an %s frontend \ -that is really useful for advanced users and easy to be used by newbies.""" \ -% (APP_DISPLAY_NAME, NMAP_DISPLAY_NAME), + 'long_description': "%s is an %s frontend that is really useful" + "for advanced users and easy to be used by newbies." % ( + APP_DISPLAY_NAME, NMAP_DISPLAY_NAME), 'version': VERSION, 'scripts': [APP_NAME], 'packages': ['zenmapCore', 'zenmapGUI', 'zenmapGUI.higwidgets', - 'radialnet', 'radialnet.bestwidgets', 'radialnet.core', 'radialnet.gui', 'radialnet.util'], + 'radialnet', 'radialnet.bestwidgets', 'radialnet.core', + 'radialnet.gui', 'radialnet.util'], 'data_files': data_files, } @@ -555,17 +577,24 @@ if 'py2exe' in sys.argv: WINDOWS_SETUP_ARGS = { 'zipfile': 'py2exe/library.zip', 'name': APP_NAME, - 'windows': [{"script": APP_NAME, - "icon_resources": [(1, "install_scripts/windows/nmap-eye.ico")]}], + 'windows': [{ + "script": APP_NAME, + "icon_resources": [(1, "install_scripts/windows/nmap-eye.ico")] + }], # On Windows we build Ndiff here in Zenmap's setup.py so the two Python # programs will share a common runtime. - 'console': [{"script": "../ndiff/scripts/ndiff", "description": "Nmap scan comparison tool"}], + 'console': [{ + "script": "../ndiff/scripts/ndiff", + "description": "Nmap scan comparison tool" + }], 'options': {"py2exe": { "compressed": 1, "optimize": 2, "packages": ["encodings"], - "includes": ["pango", "atk", "gobject", "gio", "pickle", "bz2", "encodings", "encodings.*", "cairo", "pangocairo"], - "dll_excludes": ["USP10.dll", "NSI.dll", "MSIMG32.dll", "DNSAPI.dll"] + "includes": ["pango", "atk", "gobject", "gio", "pickle", "bz2", + "encodings", "encodings.*", "cairo", "pangocairo"], + "dll_excludes": ["USP10.dll", "NSI.dll", "MSIMG32.dll", + "DNSAPI.dll"] } } } diff --git a/zenmap/zenmap b/zenmap/zenmap index d944cd814..13b676b3c 100755 --- a/zenmap/zenmap +++ b/zenmap/zenmap @@ -127,7 +127,7 @@ import sys # recursively checked, up to a limit of SYMLINK_LIMIT. # https://www.securecoding.cert.org/confluence/display/seccode/FIO15-C.+Ensure+that+file+operations+are+performed+in+a+secure+directory SYMLINK_LIMIT = 5 -def is_secure_dir(path, num_symlinks = 0): +def is_secure_dir(path, num_symlinks=0): import os import os.path import stat diff --git a/zenmap/zenmapCore/BasePaths.py b/zenmap/zenmapCore/BasePaths.py index 99f83dbc1..e7f01e757 100644 --- a/zenmap/zenmapCore/BasePaths.py +++ b/zenmap/zenmapCore/BasePaths.py @@ -126,6 +126,7 @@ import sys from zenmapCore.Name import APP_NAME + def fs_dec(s): """Decode s from the filesystem decoding, handling various possible errors.""" @@ -134,6 +135,7 @@ def fs_dec(s): enc = "UTF-8" return s.decode(enc) + def fs_enc(u): """Encode u to the filesystem decoding, handling various possible errors.""" @@ -146,20 +148,20 @@ def fs_enc(u): # home directory, because os.path.expanduser doesn't properly decode the raw # byte string from the file system encoding. You get a UnicodeDecodeError on # systems like Windows where the file system encoding is different from the -# result of sys.getdefaultencoding(). So we call os.path.expanduser with a plain -# string and decode it from the filesystem encoding. +# result of sys.getdefaultencoding(). So we call os.path.expanduser with a +# plain string and decode it from the filesystem encoding. HOME = fs_dec(os.path.expanduser("~")) # The base_paths dict in this file gives symbolic names to various files. For # example, use base_paths.target_list instead of 'target_list.txt'. -base_paths = dict(user_config_file = APP_NAME + '.conf', - user_config_dir = os.path.join(HOME, '.' + APP_NAME), - scan_profile = 'scan_profile.usp', - profile_editor = 'profile_editor.xml', - recent_scans = 'recent_scans.txt', - target_list = 'target_list.txt', - options = 'options.xml', - user_home = HOME, - db = APP_NAME + ".db", - version = APP_NAME + "_version") +base_paths = dict(user_config_file=APP_NAME + '.conf', + user_config_dir=os.path.join(HOME, '.' + APP_NAME), + scan_profile='scan_profile.usp', + profile_editor='profile_editor.xml', + recent_scans='recent_scans.txt', + target_list='target_list.txt', + options='options.xml', + user_home=HOME, + db=APP_NAME + ".db", + version=APP_NAME + "_version") diff --git a/zenmap/zenmapCore/Diff.py b/zenmap/zenmapCore/Diff.py index 1602375fe..1022a5e4e 100644 --- a/zenmap/zenmapCore/Diff.py +++ b/zenmap/zenmapCore/Diff.py @@ -136,9 +136,11 @@ import zenmapCore.Paths # The [paths] configuration from zenmap.conf, used to get ndiff_command_path. paths_config = PathsConfig() + class NdiffParseException(Exception): pass + def get_path(): """Return a value for the PATH environment variable that is appropriate for the current platform. It will be the PATH from the environment plus @@ -153,8 +155,9 @@ def get_path(): search_paths.append(path) return os.pathsep.join(search_paths) + class NdiffCommand(subprocess.Popen): - def __init__(self, filename_a, filename_b, temporary_filenames = []): + def __init__(self, filename_a, filename_b, temporary_filenames=[]): self.temporary_filenames = temporary_filenames search_paths = get_path() @@ -162,20 +165,38 @@ class NdiffCommand(subprocess.Popen): env["PATH"] = search_paths if getattr(sys, "frozen", None) == "macosx_app": # These variables are set by py2app, but they can interfere with - # Ndiff because Ndiff is also a Python application. Without removing - # these, Ndiff will attempt to run using the py2app-bundled Python - # library, and may run into version or architecture mismatches. - if env.has_key("PYTHONPATH"): + # Ndiff because Ndiff is also a Python application. Without + # removing these, Ndiff will attempt to run using the + # py2app-bundled Python library, and may run into version or + # architecture mismatches. + if "PYTHONPATH" in env: del env["PYTHONPATH"] - if env.has_key("PYTHONHOME"): + if "PYTHONHOME" in env: del env["PYTHONHOME"] - command_list = [paths_config.ndiff_command_path, "--verbose", "--", filename_a, filename_b] - self.stdout_file = tempfile.TemporaryFile(mode = "rb", prefix = APP_NAME + "-ndiff-", suffix = ".xml") + command_list = [ + paths_config.ndiff_command_path, + "--verbose", + "--", + filename_a, + filename_b + ] + self.stdout_file = tempfile.TemporaryFile( + mode="rb", + prefix=APP_NAME + "-ndiff-", + suffix=".xml" + ) log.debug("Running command: %s" % repr(command_list)) - # See zenmapCore.NmapCommand.py for an explanation of the shell argument. - subprocess.Popen.__init__(self, command_list, stdout = self.stdout_file, stderr = self.stdout_file, env = env, shell = (sys.platform == "win32")) + # shell argument explained in zenmapCore.NmapCommand.py + subprocess.Popen.__init__( + self, + command_list, + stdout=self.stdout_file, + stderr=self.stdout_file, + env=env, + shell=(sys.platform == "win32") + ) def get_scan_diff(self): self.wait() @@ -194,13 +215,17 @@ class NdiffCommand(subprocess.Popen): def kill(self): self.close() + def ndiff(scan_a, scan_b): """Run Ndiff on two scan results, which may be filenames or NmapParserSAX objects, and return a running NdiffCommand object.""" temporary_filenames = [] if isinstance(scan_a, NmapParserSAX): - fd, filename_a = tempfile.mkstemp(prefix = APP_NAME + "-diff-", suffix = ".xml") + fd, filename_a = tempfile.mkstemp( + prefix=APP_NAME + "-diff-", + suffix=".xml" + ) temporary_filenames.append(filename_a) f = os.fdopen(fd, "wb") scan_a.write_xml(f) @@ -209,7 +234,10 @@ def ndiff(scan_a, scan_b): filename_a = scan_a if isinstance(scan_b, NmapParserSAX): - fd, filename_b = tempfile.mkstemp(prefix = APP_NAME + "-diff-", suffix = ".xml") + fd, filename_b = tempfile.mkstemp( + prefix=APP_NAME + "-diff-", + suffix=".xml" + ) temporary_filenames.append(filename_b) f = os.fdopen(fd, "wb") scan_b.write_xml(f) diff --git a/zenmap/zenmapCore/I18N.py b/zenmap/zenmapCore/I18N.py index dcc4b842b..a8128a40a 100644 --- a/zenmap/zenmapCore/I18N.py +++ b/zenmap/zenmapCore/I18N.py @@ -126,6 +126,7 @@ import sys from zenmapCore.Name import APP_NAME + def get_locales(): """Get a list of locales to use based on system configuration.""" locales = [] @@ -148,6 +149,7 @@ def get_locales(): pass return locales + def install_gettext(locale_dir): try: locale.setlocale(locale.LC_ALL, '') @@ -162,8 +164,9 @@ def install_gettext(locale_dir): except ImportError: pass else: - t = gettext.translation(APP_NAME, locale_dir, languages = get_locales(), fallback = True) - t.install(unicode = True) + t = gettext.translation( + APP_NAME, locale_dir, languages=get_locales(), fallback=True) + t.install(unicode=True) # Install a dummy _ function so modules can safely use it after importing this # module, even if they don't install the gettext version. diff --git a/zenmap/zenmapCore/NSEDocParser.py b/zenmap/zenmapCore/NSEDocParser.py index df1790f0c..f5c985bcf 100644 --- a/zenmap/zenmapCore/NSEDocParser.py +++ b/zenmap/zenmapCore/NSEDocParser.py @@ -122,11 +122,13 @@ import re + class NSEDocEvent (object): - def __init__(self, type, text = None): + def __init__(self, type, text=None): self.type = type self.text = text + def nsedoc_parse_sub(text, pos): """Parse paragraph-level NSEDoc markup, inside of paragraphs and lists. Returns the position after the end of parsing followed by a list of @@ -145,6 +147,7 @@ def nsedoc_parse_sub(text, pos): return pos + m.end(), events return pos, events + def nsedoc_parse(text): """Parse text marked up for NSEDoc. This is a generator that returns a sequence of NSEDocEvents. The type of the event may be "paragraph_start", diff --git a/zenmap/zenmapCore/NetworkInventory.py b/zenmap/zenmapCore/NetworkInventory.py index 2601a5060..2c3d326e6 100644 --- a/zenmap/zenmapCore/NetworkInventory.py +++ b/zenmap/zenmapCore/NetworkInventory.py @@ -128,9 +128,11 @@ import zenmapCore.NmapParser from zenmapGUI.SearchGUI import SearchParser from SearchResult import HostSearch + class NetworkInventory(object): """This class acts as a container for aggregated scans. It is also - responsible for opening/saving the aggregation from/to persistent storage.""" + responsible for opening/saving the aggregation from/to persistent + storage.""" def __init__(self, filename=None): # A list of all scans that make up this inventory self.scans = [] @@ -162,8 +164,8 @@ class NetworkInventory(object): # Add this host to the hosts dictionary, mapped by IP address self.hosts[addr] = host.make_clone() else: - # This host is already present in the host list, so we need to update its - # info with the info held in the current host object + # This host is already present in the host list, so we need to + # update its info with the info held in the current host object old_host = self.hosts[addr] # We need to find old_host's scan date old_date = localtime(0) @@ -171,7 +173,8 @@ class NetworkInventory(object): if old_host in old_scan.get_hosts(): old_date = old_scan.get_date() new_date = scan.get_date() - self._update_host_info(old_host, host, old_date, new_date, scan) + self._update_host_info( + old_host, host, old_date, new_date, scan) self.scans.append(scan) @@ -179,7 +182,8 @@ class NetworkInventory(object): basename = os.path.basename(filename) if basename in self.filenames.values(): - # We need to generate a new filename, since this basename already exists + # We need to generate a new filename, since this basename + # already exists base = basename ext = "xml" try: @@ -195,7 +199,8 @@ class NetworkInventory(object): self.filenames[scan] = basename def remove_scan(self, scan): - """Removes a scan and any host information it contained from the inventory.""" + """Removes a scan and any host information it contained from the + inventory.""" # Note: If a scan is passed in that isn't in the inventory then this # method will throw a ValueError Exception and will not finish # Remove the scan from our scan list @@ -214,12 +219,13 @@ class NetworkInventory(object): if scan in self.filenames: del self.filenames[scan] - # For each scan in the remembered list, append it to the scan list and update - # the host list accordingly + # For each scan in the remembered list, append it to the scan list and + # update the host list accordingly for scan in scans: self.add_scan(scan) - def _update_host_info(self, old_host, new_host, old_date, new_date, new_scan): + def _update_host_info(self, old_host, new_host, + old_date, new_date, new_scan): """This function is called when a host needs to be added to the hosts dictionary, but another HostInfo object for that host already exists in the dictionary (from a previous scan). In that case, we need to @@ -232,19 +238,21 @@ class NetworkInventory(object): for new_port in new_host.ports: # Check if new_port is already present in old_host's ports for old_port in old_host.ports: - if old_port["portid"] == new_port["portid"] and old_port["protocol"] == new_port["protocol"]: + if (old_port["portid"] == new_port["portid"] and + old_port["protocol"] == new_port["protocol"]): old_list.remove(old_port) - # We update old_host's port information to reflect the latest known port state + # We update old_host's port information to reflect the + # latest known port state if old_date < new_date: index = old_host.ports.index(old_port) old_host.ports[index] = new_port - # Finished processing this new_port, we jump to the next one + # Finished processing this new_port, we jump to the next break else: - # This new_port isn't present in old_host, so we simply append it to - # old_host's port info + # This new_port isn't present in old_host, so we simply append + # it to old_host's port info old_host.ports.append(new_port) - + ports = new_scan.get_port_protocol_dict() #remove ports which are no longer up @@ -269,7 +277,8 @@ class NetworkInventory(object): if old_host.comment == "": old_host.comment = new_host.comment elif new_host.comment != "": - old_host.comment = "%s\n\n%s" % (old_host.comment, new_host.comment) + old_host.comment = "%s\n\n%s" % ( + old_host.comment, new_host.comment) # Hostnames # Replace old_host's hostname with new_host's if old_host has no @@ -279,21 +288,29 @@ class NetworkInventory(object): old_host.hostnames = new_host.hostnames # MAC address - # If there was no MAC address set in old_host, set it to whatever is in new_host.mac. - # Do the same if both hosts have a MAC address set, but new_host's address is newer. - if old_host.mac is None or \ - (old_host.mac is not None and new_host.mac is not None and old_date < new_date): + # If there was no MAC address set in old_host, set it to whatever is in + # new_host.mac. Do the same if both hosts have a MAC address set, but + # new_host's address is newer. + if (old_host.mac is None or + (old_host.mac is not None and + new_host.mac is not None and + old_date < new_date) + ): old_host.mac = new_host.mac # OS detection fields - # Replace old_host's OS detection fields with new_host's if old_host has no - # OS detection info or new_host's info is newer. - if len(new_host.osmatches) > 0 and (len(old_host.osmatches) == 0 or old_date < new_date): + # Replace old_host's OS detection fields with new_host's if old_host + # has no OS detection info or new_host's info is newer. + if (len(new_host.osmatches) > 0 and + (len(old_host.osmatches) == 0 or old_date < new_date) + ): old_host.osmatches = new_host.osmatches old_host.ports_used = new_host.ports_used # Traceroute information - if len(new_host.trace) > 0 and (len(old_host.trace) == 0 or old_date < new_date): + if (len(new_host.trace) > 0 and + (len(old_host.trace) == 0 or old_date < new_date) + ): old_host.trace = new_host.trace def get_scans(self): @@ -317,7 +334,8 @@ class NetworkInventory(object): self.add_scan(parsed, path) def open_from_dir(self, path): - """Loads all scans from the given directory into the network inventory.""" + """Loads all scans from the given directory into the network + inventory.""" from zenmapCore.NmapParser import NmapParser for filename in os.listdir(path): @@ -328,7 +346,7 @@ class NetworkInventory(object): parsed.parse_file(fullpath) self.add_scan(parsed, filename=fullpath) - def save_to_file(self, path, index, format = "xml"): + def save_to_file(self, path, index, format="xml"): """Saves the scan with the given list index into a file with a given path. With format = "xml", saves Nmap XML; otherwise saves plain text output.""" @@ -341,21 +359,24 @@ class NetworkInventory(object): f.close() def _generate_filenames(self, path): - """Generates filenames for all scans that don't already have a filename.""" - # The directory must not contain filenames other than those in the self.filenames dictionary + """Generates filenames for all scans that don't already have a + filename.""" + # The directory must not contain filenames other than those in the + # self.filenames dictionary for filename in os.listdir(path): if os.path.basename(filename) not in self.filenames.values(): - raise Exception("The destination directory contains a file (%s) that's not a part " - "of the current inventory. The inventory will not be saved." % - os.path.basename(filename)) + raise Exception("The destination directory contains a file" + "(%s) that's not a part of the current inventory." + "The inventory will not be saved." % + os.path.basename(filename)) for scan in self.scans: if scan in self.filenames: # This scan already has a filename continue - date = "%04d%02d%02d%02d%02d" % (scan.date[0], scan.date[1], scan.date[2], - scan.date[3], scan.date[4]) + date = "%04d%02d%02d%02d%02d" % (scan.date[0], scan.date[1], + scan.date[2], scan.date[3], scan.date[4]) filename = scan.get_scan_name() # Prepend the date @@ -367,20 +388,22 @@ class NetworkInventory(object): filename = filename.replace(char, "_") # Filename length check - # (http://en.wikipedia.org/wiki/Filename#Comparison_of_file_name_limitations) + # https://en.wikipedia.org/wiki/Comparison_of_file_systems#Limits if len(filename) > 250: filename = filename[:250] # TODO: Filename security checks? - # Try to open the file in append mode. If file.tell() returns a greater-than-zero - # value, this means that the file already exists and has some data in it, so we - # choose another filename until we successfully open a zero-length file. + # Try to open the file in append mode. If file.tell() returns a + # greater-than-zero value, this means that the file already exists + # and has some data in it, so we choose another filename until we + # successfully open a zero-length file. filename_full = filename + ".xml" counter = 2 while filename_full in self.filenames.values(): - # There's already a scan with this filename, so we generate a new name by appending - # the counter value before the file extension. + # There's already a scan with this filename, so we generate a + # new name by appending the counter value before the file + # extension. filename_full = "%s %s.xml" % (filename, str(counter)) counter += 1 @@ -413,12 +436,13 @@ class NetworkInventory(object): f = StringIO() parsed.write_xml(f) - scan = Scans(scan_name = parsed.scan_name, - nmap_xml_output = f.getvalue(), - date = time()) + scan = Scans(scan_name=parsed.scan_name, + nmap_xml_output=f.getvalue(), + date=time()) + class FilteredNetworkInventory(NetworkInventory): - def __init__(self, filename = None): + def __init__(self, filename=None): NetworkInventory.__init__(self, filename) # A dictionary listing host filtering criteria @@ -459,18 +483,24 @@ class FilteredNetworkInventory(NetworkInventory): return self.filtered_hosts else: return NetworkInventory.get_hosts(self) + def get_hosts_up(self): if len(self.search_dict) > 0: - return filter(lambda h: h.get_state() == 'up', self.filtered_hosts) + return filter(lambda h: h.get_state() == 'up', + self.filtered_hosts) else: return NetworkInventory.get_hosts_up(self) + def get_hosts_down(self): if len(self.search_dict) > 0: - return filter(lambda h: h.get_state() == 'down', self.filtered_hosts) + return filter(lambda h: h.get_state() == 'down', + self.filtered_hosts) else: return NetworkInventory.get_hosts_down(self) + def get_total_host_count(self): return len(self.hosts) + def _match_all_args(self, host, operator, args): """A helper function that calls the matching function for the given operator and each of its arguments.""" @@ -479,48 +509,63 @@ class FilteredNetworkInventory(NetworkInventory): if arg != "" and arg[0] == "!": arg = arg[1:] positive = False - if positive != self.__getattribute__("match_%s" % operator)(host, arg): + if positive != self.__getattribute__( + "match_%s" % operator)(host, arg): # No match for this operator return False else: # if the operator is not supported, pretend its true # All arguments for this operator produced a match return True + def get_host_count(self): return len(self.network_inventory.hosts) + def match_keyword(self, host, keyword): return self.match_os(host, keyword) or\ self.match_target(host, keyword) or\ self.match_service(host, keyword) + def match_target(self, host, name): return HostSearch.match_target(host, name) + def match_in_route(self, host, hop): hops = host.get_trace().get('hops', []) return hop in hops + def match_hostname(self, host, hostname): return HostSearch.match_hostname(host, hostname) + def match_service(self, host, service): return HostSearch.match_service(host, service) + def match_os(self, host, os): return HostSearch.match_os(host, os) + def match_open(self, host, portno): host_ports = host.get_ports() return HostSearch.match_port(host_ports, portno, "open") + def match_closed(self, host, portno): host_ports = host.get_ports() return HostSearch.match_port(host_ports, portno, "closed") + def match_filtered(self, host, portno): host_ports = host.get_ports() return HostSearch.match_port(host_ports, portno, "filtered") + def match_unfiltered(self, host, portno): host_ports = host.get_ports() return HostSearch.match_port(host_ports, portno, "unfiltered") + def match_open_filtered(self, host, portno): host_ports = host.get_ports() return HostSearch.match_port(host_ports, portno, "open|filtered") + def match_closed_filtered(self, host, portno): host_ports = host.get_ports() return HostSearch.match_port(host_ports, portno, "closed|filtered") + def apply_filter(self, filter_text): self.filter_text = filter_text.lower() self.search_parser.update(self.filter_text) @@ -537,10 +582,11 @@ class FilteredNetworkInventory(NetworkInventory): # host satisfies all conditions self.filtered_hosts.append(host) + class NetworkInventoryTest(unittest.TestCase): def test_no_external_modification(self): - """Test that HostInfo objects passed into the inventory are not modified - during aggregation.""" + """Test that HostInfo objects passed into the inventory are not + modified during aggregation.""" scan_1 = zenmapCore.NmapParser.ParserBasics() host_a = zenmapCore.NmapParser.HostInfo() host_a.hostnames = ["a"] @@ -564,28 +610,30 @@ class NetworkInventoryTest(unittest.TestCase): self.assertEqual(scan_1.nmap["hosts"], [host_a]) self.assertEqual(scan_2.nmap["hosts"], [host_b]) self.assertEqual(inv.get_hosts_up()[0].hostnames, ["b"]) + def test_cancel_and_remove_scan(self): - """Test that canceling and removing a scan does not blow away the inventory hosts""" - added_ips = ['10.0.0.1','10.0.0.2'] + """Test that canceling and removing a scan does not blow away the + inventory hosts""" + added_ips = ['10.0.0.1', '10.0.0.2'] removed_ips = ['10.0.0.3'] scan_1 = zenmapCore.NmapParser.ParserBasics() host_a = zenmapCore.NmapParser.HostInfo() host_a.hostnames = ["a"] - host_a.set_ip({'addr':added_ips[0]}) + host_a.set_ip({'addr': added_ips[0]}) scan_1.start = "1000000000" scan_1.nmap["hosts"] = [host_a] scan_2 = zenmapCore.NmapParser.ParserBasics() host_b = zenmapCore.NmapParser.HostInfo() host_b.hostnames = ["b"] - host_b.set_ip({'addr':added_ips[1]}) + host_b.set_ip({'addr': added_ips[1]}) scan_2.start = "1000000001" scan_2.nmap["hosts"] = [host_b] scan_3 = zenmapCore.NmapParser.ParserBasics() host_c = zenmapCore.NmapParser.HostInfo() host_c.hostnames = ["b"] - host_c.set_ip({'addr':removed_ips[0]}) + host_c.set_ip({'addr': removed_ips[0]}) scan_3.start = "1000000001" scan_3.nmap["hosts"] = [host_c] @@ -600,6 +648,7 @@ class NetworkInventoryTest(unittest.TestCase): self.assertEqual(host_a.hostnames, ["a"]) self.assertEqual(host_b.hostnames, ["b"]) + class FilteredNetworkInventoryTest(unittest.TestCase): def test_filter(self): """Test that the filter still works after moving code to the """ @@ -613,6 +662,7 @@ class FilteredNetworkInventoryTest(unittest.TestCase): inv.apply_filter(filter_text) assert(len(inv.get_hosts()) == 2) + class PortChangeTest(unittest.TestCase): def test_port(self): """Verify that the port status (open/filtered/closed) is diplayed """ \ @@ -632,17 +682,17 @@ class PortChangeTest(unittest.TestCase): assert(len(inv.get_hosts()[0].ports) == 0) # Additional test case for when the two scans have port scan ranges - # which do not overlap. Example nmap -F -sU versus - # nmap -F scanme.nmap.org + # which do not overlap. Example nmap -F -sU versus + # nmap -F scanme.nmap.org inv = NetworkInventory() scan4 = NmapParser() scan4.parse_file("test/xml_test16.xml") inv.add_scan(scan4) - assert(len(inv.get_hosts()[0].ports)==3) + assert(len(inv.get_hosts()[0].ports) == 3) scan5 = NmapParser() scan5.parse_file("test/xml_test17.xml") inv.add_scan(scan5) - assert(len(inv.get_hosts()[0].ports)==7) + assert(len(inv.get_hosts()[0].ports) == 7) if __name__ == "__main__": unittest.main() diff --git a/zenmap/zenmapCore/NmapCommand.py b/zenmap/zenmapCore/NmapCommand.py index 1eabd4035..99bd65c60 100644 --- a/zenmap/zenmapCore/NmapCommand.py +++ b/zenmap/zenmapCore/NmapCommand.py @@ -152,6 +152,7 @@ paths_config = PathsConfig() log.debug(">>> Platform: %s" % sys.platform) + def wrap_file_in_preferred_encoding(f): """Wrap an open file to automatically decode its contents when reading from the encoding given by locale.getpreferredencoding, or just return the file @@ -184,17 +185,19 @@ def wrap_file_in_preferred_encoding(f): return f + def escape_nmap_filename(filename): """Escape '%' characters so they are not interpreted as strftime format specifiers, which are not supported by Zenmap.""" return filename.replace("%", "%%") + class NmapCommand(object): """This class represents an Nmap command line. It is responsible for starting, stopping, and returning the results from a command-line scan. A command line is represented as a string but it is split into a list of arguments for execution. - + The normal output (stdout and stderr) are written to the file object self.stdout_file.""" @@ -231,7 +234,8 @@ class NmapCommand(object): self.ops[op] = escape_nmap_filename(self.ops[op]) if self.xml_is_temp: - self.xml_output_filename = tempfile.mktemp(prefix = APP_NAME + "-", suffix = ".xml") + self.xml_output_filename = tempfile.mktemp( + prefix=APP_NAME + "-", suffix=".xml") self.ops["-oX"] = escape_nmap_filename(self.xml_output_filename) log.debug(">>> Temporary files:") @@ -261,7 +265,8 @@ class NmapCommand(object): else: try: import ctypes - ctypes.windll.kernel32.TerminateProcess(int(self.command_process._handle), -1) + ctypes.windll.kernel32.TerminateProcess( + int(self.command_process._handle), -1) except: pass @@ -279,13 +284,13 @@ class NmapCommand(object): search_paths.append(path) return os.pathsep.join(search_paths) - def run_scan(self, stderr = None): + def run_scan(self, stderr=None): """Run the command represented by this class.""" # We don't need a file name for stdout output, just a handle. A # TemporaryFile is deleted as soon as it is closed, and in Unix is # unlinked immediately after creation so it's not even visible. - f = tempfile.TemporaryFile(mode = "rb", prefix = APP_NAME + "-stdout-") + f = tempfile.TemporaryFile(mode="rb", prefix=APP_NAME + "-stdout-") self.stdout_file = wrap_file_in_preferred_encoding(f) if stderr is None: stderr = f @@ -303,7 +308,8 @@ class NmapCommand(object): # This keeps a terminal window from opening. startupinfo = subprocess.STARTUPINFO() try: - startupinfo.dwFlags |= subprocess._subprocess.STARTF_USESHOWWINDOW + startupinfo.dwFlags |= \ + subprocess._subprocess.STARTF_USESHOWWINDOW except AttributeError: # This name is used before Python 2.6.5. startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW @@ -312,7 +318,7 @@ class NmapCommand(object): stdin=subprocess.PIPE, stdout=f, stderr=stderr, - startupinfo = startupinfo, + startupinfo=startupinfo, env=env) def scan_state(self): @@ -327,15 +333,18 @@ class NmapCommand(object): state = self.command_process.poll() if state == None: - return True # True means that the process is still running + return True # True means that the process is still running elif state == 0: - return False # False means that the process had a successful exit + return False # False means that the process had a successful exit else: log.warning("An error occurred during the scan execution!") - log.warning("Command that raised the exception: '%s'" % self.ops.render_string()) + log.warning("Command that raised the exception: '%s'" % + self.ops.render_string()) log.warning("Scan output:\n%s" % self.get_output()) - raise Exception("An error occurred during the scan execution!\n\n'%s'" % self.get_output()) + raise Exception( + "An error occurred during the scan execution!\n\n'%s'" % + self.get_output()) def get_output(self): """Return the complete contents of the self.stdout_file. This modifies @@ -348,4 +357,5 @@ class NmapCommand(object): return self.xml_output_filename if __name__ == '__main__': - unittest.TextTestRunner().run(unittest.TestLoader().loadTestsFromTestCase(SplitQuotedTest)) + unittest.TextTestRunner().run( + unittest.TestLoader().loadTestsFromTestCase(SplitQuotedTest)) diff --git a/zenmap/zenmapCore/NmapOptions.py b/zenmap/zenmapCore/NmapOptions.py index 4f029bd04..5a24bbf5d 100644 --- a/zenmap/zenmapCore/NmapOptions.py +++ b/zenmap/zenmapCore/NmapOptions.py @@ -2,8 +2,8 @@ # This is an Nmap command line parser. It has two main parts: # -# getopt_long_only_extras, which is like getopt_long_only with robust handling -# of unknown options. +# getopt_long_only_extras, which is like getopt_long_only with robust +# handling of unknown options. # # NmapOptions, a class representing a set of Nmap options. # @@ -30,9 +30,11 @@ # >>> ops["-v"] = 2 # >>> ops["-oX"] = "output.xml" # >>> ops.render() -# ['C:\\Program Files\\Nmap\\nmap.exe', '-v', '-v', '-oX', 'output.xml', '--script', 'safe', 'localhost'] +# ['C:\\Program Files\\Nmap\\nmap.exe', '-v', '-v', '-oX', 'output.xml', +# '--script', 'safe', 'localhost'] # >>> ops.render_string() -# '"C:\\Program Files\\Nmap\\nmap.exe" -v -v -oX output.xml --script safe localhost' +# '"C:\\Program Files\\Nmap\\nmap.exe" -v -v -oX output.xml\ +# --script safe localhost' # # A primary design consideration was robust handling of unknown options. That # gives this code a degree of independence from Nmap's own list of options. If @@ -45,17 +47,17 @@ # nmap -x -e eth0 scanme.nmap.org # If -x, whatever it is, does not take an argument, it is equivalent to # nmap -e eth0 scanme.nmap.org -x -# that is, a scan of scanme.nmap.org over interface eth0. But if it does take an -# argument, its argument is "-e", and the command line is the same as +# that is, a scan of scanme.nmap.org over interface eth0. But if it does take +# an argument, its argument is "-e", and the command line is the same as # nmap eth0 scanme.nmap.org -x -e # which is a scan of the two hosts eth0 and scanme.nmap.org, over the default # interface. In either case scanme.nmap.org is a target but the other arguments -# are ambiguous. To resolve this, once an unknown option is found, all following -# arguments that can be interpreted ambiguously are removed with it and placed -# in the extras, with normal option processing resumed only when there is no -# more ambiguity. This ensures that such options maintain their relative order -# when rendered again to output. In this example "-x -e eth0" will always appear -# in that order, and the -e option will be uninterpreted. +# are ambiguous. To resolve this, once an unknown option is found, all +# following arguments that can be interpreted ambiguously are removed with it +# and placed in the extras, with normal option processing resumed only when +# there is no more ambiguity. This ensures that such options maintain their +# relative order when rendered again to output. In this example "-x -e eth0" +# will always appear in that order, and the -e option will be uninterpreted. # # To add a new option, one should do the following: # 1) Add a test case to the NmapOptionsTest::test_options() method for the new @@ -79,6 +81,7 @@ # get_option_check_auxiliary_widget in OptionBuilder.py. # 7) Make sure the test case works now. + class option: """A single option, part of a pool of potential options. It's just a name and a flag saying if the option takes no argument, if an agument is @@ -91,6 +94,7 @@ class option: self.name = name self.has_arg = has_arg + def split_quoted(s): """Like str.split, except that no splits occur inside quoted strings, and quoted strings are unquoted.""" @@ -114,8 +118,8 @@ def split_quoted(s): i += 1 if i < len(s): c = s[i] - # Otherwise, ignore the error and leave the backslash at - # the end of the string. + # Otherwise, ignore the error and leave the backslash + # at the end of the string. part.append(c) i += 1 else: @@ -127,6 +131,7 @@ def split_quoted(s): return r + def maybe_quote(s): """Return s quoted if it needs to be, otherwise unchanged.""" for c in s: @@ -146,9 +151,11 @@ def maybe_quote(s): return "\"" + "".join(r) + "\"" + def join_quoted(l): return " ".join([maybe_quote(x) for x in l]) + def make_options(short_opts, long_opts): """Parse a short option specification string and long option tuples into a list of option objects.""" @@ -176,6 +183,7 @@ def make_options(short_opts, long_opts): lookup_option_cache = {} + def lookup_option(name, options): """Find an option with the given (possibly abbreviated) name. None is returned if no options match or if the name is ambiguous (more than one @@ -197,7 +205,8 @@ def lookup_option(name, options): return name.replace("_", "-") name = canonicalize_name(name) - matches = [o for o in options if canonicalize_name(o.name).startswith(name)] + matches = [o for o in options + if canonicalize_name(o.name).startswith(name)] if len(matches) == 0: # No match. lookup_option_cache[cache_code] = None @@ -215,19 +224,22 @@ def lookup_option(name, options): lookup_option_cache[cache_code] = None return lookup_option_cache[cache_code] + def split_option(cmd_arg, options): """Split an option into a name, argument (if any), and possible remainder. - It is not an error if the option does not include an argument even though it - is required; the caller must take the argument from the next command-line - argument. The remainder is what's left over after stripping a single short - option that doesn't take an argument. At most one of argument and remainder - will be non-None. + It is not an error if the option does not include an argument even though + it is required; the caller must take the argument from the next + command-line argument. The remainder is what's left over after stripping a + single short option that doesn't take an argument. At most one of argument + and remainder will be non-None. Examples: >>> split_option("-v", [option("v", option.NO_ARGUMENT)]) ('v', None, None) - >>> split_option("--min-rate", [option("min-rate", option.REQUIRED_ARGUMENT)]) + >>> split_option("--min-rate", + ... [option("min-rate", option.REQUIRED_ARGUMENT)]) ('min-rate', None, None) - >>> split_option("--min-rate=100", [option("min-rate", option.REQUIRED_ARGUMENT)]) + >>> split_option("--min-rate=100", + ... [option("min-rate", option.REQUIRED_ARGUMENT)]) ('min-rate', '100', None) >>> split_option("-d9", [option("d", option.OPTIONAL_ARGUMENT)]) ('d', '9', None) @@ -273,15 +285,17 @@ def split_option(cmd_arg, options): else: assert False, cmd_arg + def get_option(cmd_args, options): """Find and return the first option (plus a possible option argument) or positional argument from the command-line option list in cmd_args. The return value will have one of the following forms: - a string, representing a positional argument; - an (option, argument) pair (argument may be None); - a (None, extra, ...) tuple, where extra, ... is a chain of an unknown option - and its following arguments that cannot be interpreted unambiguously; or - None, at the end of the option list.""" + * a string, representing a positional argument; + * an (option, argument) pair (argument may be None); + * a (None, extra, ...) tuple, where extra, ... is a chain of an unknown + option and its following arguments that cannot be interpreted + unambiguously; or + * None, at the end of the option list.""" if len(cmd_args) == 0: return None cmd_arg = cmd_args.pop(0) @@ -305,9 +319,9 @@ def get_option(cmd_args, options): return (None, cmd_arg) else: extras = [None, cmd_arg] - # We found an unknown option but we have a problem--we don't know if - # it takes an argument or not. So what we do is, we simulate what - # would happen both if the option took and argument and if it + # We found an unknown option but we have a problem--we don't know + # if it takes an argument or not. So what we do is, we simulate + # what would happen both if the option took and argument and if it # didn't. The sync function does that by calling this function in a # loop. rest = sync(cmd_args[1:], cmd_args[:], options) @@ -332,6 +346,7 @@ def get_option(cmd_args, options): else: return (option.name, arg) + def sync(a, b, options): """Given two command-line argument lists, incrementally get an option from whichever is longer until both lists are equal. Return the resulting @@ -343,15 +358,17 @@ def sync(a, b, options): get_option(b, options) return a + def getopt_long_only_extras(cmd_args, short_opts, long_opts): """This is a generator version of getopt_long_only that additionally has robust handling of unknown options. Each of the items in the sequence it yields will be one of the following: - a string, representing a positional argument; - an (option, argument) pair (argument may be None); - a (None, extra, ...) tuple, where extra, ... is a chain of an unknown option - and its following arguments that cannot be interpreted unambiguously; or - None, at the end of the option list.""" + * a string, representing a positional argument; + * an (option, argument) pair (argument may be None); + * a (None, extra, ...) tuple, where extra, ... is a chain of an unknown + option and its following arguments that cannot be interpreted + unambiguously; or + * None, at the end of the option list.""" options = make_options(short_opts, long_opts) # get_option modifies its list of arguments in place. Don't modify the # original list. @@ -362,6 +379,7 @@ def getopt_long_only_extras(cmd_args, short_opts, long_opts): break yield result + class NmapOptions(object): SHORT_OPTIONS = "6Ab:D:d::e:Ffg:hi:M:m:nO::o:P:p:RrS:s:T:v::V" LONG_OPTIONS = ( @@ -492,7 +510,8 @@ class NmapOptions(object): def _set_executable(self, executable): self._executable = executable - executable = property(lambda self: self._executable or "nmap", _set_executable) + executable = property(lambda self: self._executable or "nmap", + _set_executable) def canonicalize_name(self, name): opt, arg, remainder = split_option(name, self.options) @@ -563,7 +582,8 @@ class NmapOptions(object): "webxml", ): self["--" + opt] = True - elif opt in ("b", "D", "e", "g", "i", "iL", "m", "M", "o", "oA", "oG", "oM", "oN", "oS", "oX", "p", "S", "sI"): + elif opt in ("b", "D", "e", "g", "i", "iL", "m", "M", "o", "oA", "oG", + "oM", "oN", "oS", "oX", "p", "S", "sI"): assert arg is not None if self["-" + opt] is None: self["-" + opt] = arg @@ -617,7 +637,8 @@ class NmapOptions(object): try: self["-d"] = int(arg) except ValueError: - if reduce(lambda x, y: x and y, map(lambda z: z == "d", arg), True): + if reduce(lambda x, y: x and y, + map(lambda z: z == "d", arg), True): self.setdefault("-d", 0) self["-d"] += len(arg) + 1 else: @@ -646,7 +667,8 @@ class NmapOptions(object): self.extras.append("-O%s" % arg) elif opt == "P": type, ports = arg[:1], arg[1:] - if type == "0" or type == "D" or type == "N" or type == "n" and ports == "": + if (type == "0" or type == "D" or type == "N" or + type == "n" and ports == ""): self["-Pn"] = True elif (type == "" or type == "I" or type == "E") and ports == "": self["-PE"] = True @@ -693,7 +715,8 @@ class NmapOptions(object): try: self["-v"] = int(arg) except ValueError: - if reduce(lambda x, y: x and y, map(lambda z: z == "v", arg), True): + if reduce(lambda x, y: x and y, + map(lambda z: z == "v", arg), True): self.setdefault("-v", 0) self["-v"] += len(arg) + 1 else: @@ -707,7 +730,8 @@ class NmapOptions(object): if len(opt_list) > 0: self.executable = opt_list[0] - for result in getopt_long_only_extras(opt_list[1:], self.SHORT_OPTIONS, self.LONG_OPTIONS): + for result in getopt_long_only_extras( + opt_list[1:], self.SHORT_OPTIONS, self.LONG_OPTIONS): self.handle_result(result) def parse_string(self, opt_string): @@ -716,7 +740,8 @@ class NmapOptions(object): def render(self): opt_list = [] - for opt in ("-sA", "-sC", "-sF", "-sL", "-sM", "-sN", "-sO", "-sn", "-sR", "-sS", "-sT", "-sU", "-sV", "-sW", "-sX", "-sY", "-sZ"): + for opt in ("-sA", "-sC", "-sF", "-sL", "-sM", "-sN", "-sO", "-sn", + "-sR", "-sS", "-sT", "-sU", "-sV", "-sW", "-sX", "-sY", "-sZ"): if self[opt]: opt_list.append(opt) @@ -865,6 +890,7 @@ class NmapOptions(object): import doctest import unittest + class NmapOptionsTest(unittest.TestCase): def test_clear(self): """Test that a new object starts without defining any options, that the @@ -901,7 +927,8 @@ class NmapOptionsTest(unittest.TestCase): TEST = "nmap -T4 -A -v localhost --webxml" ops = NmapOptions() ops.parse_string(TEST) - self.assertTrue(type(ops.render()) == list, "type == %s" % type(ops.render)) + self.assertTrue(type(ops.render()) == list, + "type == %s" % type(ops.render)) def test_quoted(self): """Test that strings can be quoted.""" @@ -1123,7 +1150,8 @@ class NmapOptionsTest(unittest.TestCase): ops.parse_string("nmap -min-rate=100") self.assertTrue(ops["--min-rate"] == "100") - # Short options not taking an argument can be followed by a long option. + # Short options not taking an argument can be followed by a long + # option. ops.parse_string("nmap -nFmin-rate 100") self.assertTrue(ops["-n"]) self.assertTrue(ops["-F"]) @@ -1155,8 +1183,8 @@ class NmapOptionsTest(unittest.TestCase): self.assertEqual(ops["--nonoption"], None) def test_canonical_option_names(self): - """Test that equivalent option names are properly canonicalized, so that - ops["--timing"] and ops["-T"] mean the same thing, for example.""" + """Test that equivalent option names are properly canonicalized, so + that ops["--timing"] and ops["-T"] mean the same thing, for example.""" EQUIVS = ( ("--debug", "-d"), ("--help", "-h"), @@ -1334,11 +1362,17 @@ class NmapOptionsTest(unittest.TestCase): ops.parse_string("nmap " + test) opt_list_1 = ops.render() self.assertTrue(len(opt_list_1) > 1, "%s missing on render" % test) - self.assertTrue(len(ops.extras) == 0, "%s caused extras: %s" % (test, repr(ops.extras))) + self.assertTrue(len(ops.extras) == 0, + "%s caused extras: %s" % (test, repr(ops.extras))) ops.parse(opt_list_1) opt_list_2 = ops.render() - self.assertTrue(opt_list_1 == opt_list_2, "Result of parsing and rendering %s not parsable again" % test) - self.assertTrue(len(ops.extras) == 0, "Result of parsing and rendering %s left extras: %s" % (test, ops.extras)) + self.assertTrue(opt_list_1 == opt_list_2, + "Result of parsing and rendering %s not parsable again" % ( + test)) + self.assertTrue(len(ops.extras) == 0, + "Result of parsing and rendering %s left extras: %s" % ( + test, ops.extras)) + class SplitQuotedTest(unittest.TestCase): """A unittest class that tests the split_quoted function.""" @@ -1359,6 +1393,7 @@ class SplitQuotedTest(unittest.TestCase): self.assertEqual(split_quoted('\\"\\""'), ['\\"']) self.assertEqual(split_quoted('"\\"\\""'), ['""']) + if __name__ == "__main__": doctest.testmod() unittest.main() diff --git a/zenmap/zenmapCore/NmapParser.py b/zenmap/zenmapCore/NmapParser.py index 9b0cc015d..b7ee816a2 100644 --- a/zenmap/zenmapCore/NmapParser.py +++ b/zenmap/zenmapCore/NmapParser.py @@ -144,9 +144,10 @@ from zenmapCore.StringPool import unique # The version of the Nmap DTD this file understands and emits. XML_OUTPUT_VERSION = "1.04" + class HostInfo(object): def __init__(self): - self.comment = None; + self.comment = None self._tcpsequence = {} self._osmatches = [] self._ports = [] @@ -233,13 +234,14 @@ class HostInfo(object): """Return the OS match with the highest accuracy.""" if not self._osmatches: return None + def osmatch_key(osmatch): try: return -float(osmatch["accuracy"]) except ValueError: return 0 - return sorted(self._osmatches, key = osmatch_key)[0] + return sorted(self._osmatches, key=osmatch_key)[0] # ports_used is a list like # [{'state': u'open', 'portid': u'22', 'proto': u'tcp'}, @@ -262,7 +264,7 @@ class HostInfo(object): return self._uptime # Avoid empty dict return - return {"seconds":"", "lastboot":""} + return {"seconds": "", "lastboot": ""} # ports is an array containing dicts of the form # {'port_state': u'open', 'portid': u'22', 'protocol': u'tcp', @@ -323,14 +325,16 @@ class HostInfo(object): l.append((1, socket.inet_aton(self.ip["addr"]))) if self.ipv6: try: - l.append((1, socket.inet_pton(socket.AF_INET6, self.ipv6["addr"]))) + l.append((1, + socket.inet_pton(socket.AF_INET6, self.ipv6["addr"]))) except AttributeError: # Windows doesn't have socket.inet_pton. Go alphabetical. # Encode to a byte string for possible comparison with binary # address strings (which can't be converted to unicode). l.append((1, self.ipv6["addr"].encode("utf-8"))) if self.mac: - l.append((3, "".join([chr(int(x, 16)) for x in self.mac["addr"].split(":")]))) + l.append((3, "".join( + chr(int(x, 16)) for x in self.mac["addr"].split(":")))) l.sort() return l @@ -386,7 +390,8 @@ class HostInfo(object): return self.get_port_count_by_states(('open', 'open|filtered')) def get_filtered_ports(self): - return self.get_port_count_by_states(('filtered', 'open|filtered', 'closed|filtered')) + return self.get_port_count_by_states( + ('filtered', 'open|filtered', 'closed|filtered')) def get_closed_ports(self): return self.get_port_count_by_states(('closed', 'closed|filtered')) @@ -395,7 +400,7 @@ class HostInfo(object): scanned = 0 for p in self.ports: - scanned+=1 + scanned += 1 for extra in self.get_extraports(): scanned += int(extra["count"]) @@ -405,14 +410,16 @@ class HostInfo(object): def get_services(self): services = [] for p in self.ports: - services.append({"service_name":p.get("service_name", _("unknown")), - "portid":p.get("portid", ""), - "service_version":p.get("service_version", - _("Unknown version")), - "service_product":p.get("service_product", ""), - "service_extrainfo":p.get("service_extrainfo", ""), - "port_state":p.get("port_state", _("Unknown")), - "protocol":p.get("protocol", "")}) + services.append({ + "service_name": p.get("service_name", _("unknown")), + "portid": p.get("portid", ""), + "service_version": p.get("service_version", + _("Unknown version")), + "service_product": p.get("service_product", ""), + "service_extrainfo": p.get("service_extrainfo", ""), + "port_state": p.get("port_state", _("Unknown")), + "protocol": p.get("protocol", "") + }) return services def get_trace(self): @@ -448,19 +455,22 @@ class HostInfo(object): services = property(get_services) trace = property(get_trace, set_trace) + class ParserBasics(object): - def __init__ (self): + def __init__(self): # This flag informs us whether the XML output file is temporary (True), # or user specified (False). If any of them is user-specified, it # doesn't get stripped out of the command string in set_nmap_command. self.xml_is_temp = True - self.nmap = {'nmaprun':{},\ - 'scaninfo':[],\ - 'verbose':'',\ - 'debugging':'',\ - 'hosts':[],\ - 'runstats':{}} + self.nmap = { + 'nmaprun': {}, + 'scaninfo': [], + 'verbose': '', + 'debugging': '', + 'hosts': [], + 'runstats': {} + } self.ops = NmapOptions() self._nmap_output = None @@ -490,13 +500,13 @@ class ParserBasics(object): def set_nmap_output(self, nmap_output): self._nmap_output = nmap_output - def get_debugging_level (self): + def get_debugging_level(self): return self.nmap.get('debugging', '') def set_debugging_level(self, level): self.nmap['debugging'] = level - def get_verbose_level (self): + def get_verbose_level(self): return self.nmap.get('verbose', '') def set_verbose_level(self, level): @@ -508,7 +518,7 @@ class ParserBasics(object): def set_scaninfo(self, info): self.nmap['scaninfo'] = info - def get_services_scanned (self): + def get_services_scanned(self): if self._services_scanned == None: return self._services_scanned @@ -519,10 +529,10 @@ class ParserBasics(object): self._services_scanned = ','.join(services) return self._services_scanned - def set_services_scanned (self, services_scanned): + def set_services_scanned(self, services_scanned): self._services_scanned = services_scanned - def get_nmap_command (self): + def get_nmap_command(self): return self.ops.render_string() def set_nmap_command(self, command): @@ -531,19 +541,19 @@ class ParserBasics(object): self.ops["-oX"] = None self.nmap['nmaprun']['args'] = self.ops.render_string() - def get_scan_type (self): + def get_scan_type(self): types = [] for t in self.nmap.get('scaninfo', []): types.append(t['type']) return types - def get_protocol (self): + def get_protocol(self): protocols = [] for proto in self.nmap.get('scaninfo', []): protocols.append(proto['protocol']) return protocols - def get_num_services (self): + def get_num_services(self): if self._num_services == None: return self._num_services @@ -554,12 +564,12 @@ class ParserBasics(object): self._num_services = num return self._num_services - def set_num_services (self, num_services): + def set_num_services(self, num_services): self._num_services = num_services - def get_date (self): + def get_date(self): epoch = int(self.nmap['nmaprun'].get('start', '0')) - return time.localtime (epoch) + return time.localtime(epoch) def get_start(self): return self.nmap['nmaprun'].get('start', '0') @@ -601,13 +611,13 @@ in epoch format!") def get_formatted_date(self): return time.strftime("%B %d, %Y - %H:%M", self.get_date()) - def get_scanner (self): + def get_scanner(self): return self.nmap['nmaprun'].get('scanner', '') def set_scanner(self, scanner): self.nmap['nmaprun']['scanner'] = scanner - def get_scanner_version (self): + def get_scanner_version(self): return self.nmap['nmaprun'].get('version', '') def set_scanner_version(self, version): @@ -634,7 +644,7 @@ in epoch format!") return [] return [host.ipv6 for host in hosts if host.ipv6 is not None] - def get_hostnames (self): + def get_hostnames(self): hostnames = [] for host in self.nmap.get('hosts', []): hostnames += host.get_hostnames() @@ -667,7 +677,7 @@ in epoch format!") def set_hosts_scanned(self, scanned): self.nmap['runstats']['hosts_scanned'] = int(scanned) - def get_finish_time (self): + def get_finish_time(self): return time.localtime(int(self.nmap['runstats'].get('finished_time', '0'))) @@ -686,7 +696,8 @@ in epoch format!") if scan_name: return scan_name if self.profile_name and self.get_targets(): - return _("%s on %s") % (self.profile_name, join_quoted(self.get_targets())) + return _("%s on %s") % (self.profile_name, + join_quoted(self.get_targets())) return self.get_nmap_command() def set_scan_name(self, scan_name): @@ -710,8 +721,8 @@ in epoch format!") ports[int(item)] = [] ports[int(item)].append(scaninfo['protocol']) else: - begin,end = item.split('-') - for port in range(int(begin),int(end)+1): + begin, end = item.split('-') + for port in range(int(begin), int(end) + 1): if int(port) not in ports: ports[int(port)] = [] ports[int(port)].append(scaninfo['protocol']) @@ -752,6 +763,7 @@ in epoch format!") _num_services = None _services_scanned = None + class NmapParserSAX(ParserBasics, ContentHandler): def __init__(self): ParserBasics.__init__(self) @@ -793,14 +805,15 @@ class NmapParserSAX(ParserBasics, ContentHandler): def _parse_nmaprun(self, attrs): run_tag = "nmaprun" - if self._nmap_output is None and attrs.has_key("nmap_output"): + if self._nmap_output is None and "nmap_output" in attrs: self._nmap_output = attrs["nmap_output"] self.nmap[run_tag]["profile_name"] = attrs.get("profile_name", "") self.nmap[run_tag]["start"] = attrs.get("start", "") self.nmap[run_tag]["args"] = attrs.get("args", "") self.nmap[run_tag]["scanner"] = attrs.get("scanner", "") self.nmap[run_tag]["version"] = attrs.get("version", "") - self.nmap[run_tag]["xmloutputversion"] = attrs.get("xmloutputversion", "") + self.nmap[run_tag]["xmloutputversion"] = attrs.get( + "xmloutputversion", "") self.nmap_command = self.nmap[run_tag]["args"] @@ -844,9 +857,9 @@ class NmapParserSAX(ParserBasics, ContentHandler): self.host_info.set_state(unique(attrs.get("state", ""))) def _parse_host_address(self, attrs): - address_attributes = {"type":unique(attrs.get("addrtype", "")), - "vendor":attrs.get("vendor", ""), - "addr":attrs.get("addr", "")} + address_attributes = {"type": unique(attrs.get("addrtype", "")), + "vendor": attrs.get("vendor", ""), + "addr": attrs.get("addr", "")} if address_attributes["type"] == "ipv4": self.host_info.set_ip(address_attributes) @@ -856,16 +869,16 @@ class NmapParserSAX(ParserBasics, ContentHandler): self.host_info.set_mac(address_attributes) def _parse_host_hostname(self, attrs): - self.list_hostnames.append({"hostname":attrs.get("name", ""), - "hostname_type":attrs.get("type", "")}) + self.list_hostnames.append({"hostname": attrs.get("name", ""), + "hostname_type": attrs.get("type", "")}) def _parse_host_extraports(self, attrs): - self.list_extraports.append({"state":unique(attrs.get("state", "")), - "count":attrs.get("count", "")}) + self.list_extraports.append({"state": unique(attrs.get("state", "")), + "count": attrs.get("count", "")}) def _parse_host_port(self, attrs): - self.dic_port = {"protocol":unique(attrs.get("protocol", "")), - "portid":unique(attrs.get("portid", ""))} + self.dic_port = {"protocol": unique(attrs.get("protocol", "")), + "portid": unique(attrs.get("portid", ""))} def _parse_host_port_state(self, attrs): self.dic_port["port_state"] = unique(attrs.get("state", "")) @@ -886,10 +899,12 @@ class NmapParserSAX(ParserBasics, ContentHandler): self.list_osmatch.append(osmatch) def _parse_host_portused(self, attrs): - self.list_portused.append(self._parsing(attrs, ['state', 'proto', 'portid'], [])) + self.list_portused.append(self._parsing( + attrs, ['state', 'proto', 'portid'], [])) def _parse_host_osclass(self, attrs): - self.list_osclass.append(self._parsing(attrs, ['type', 'vendor', 'osfamily', 'osgen'], ['accuracy'])) + self.list_osclass.append(self._parsing( + attrs, ['type', 'vendor', 'osfamily', 'osgen'], ['accuracy'])) def _parsing(self, attrs, unique_names, other_names): # Returns a dict with the attributes of a given tag with the @@ -902,17 +917,20 @@ class NmapParserSAX(ParserBasics, ContentHandler): return dic def _parse_host_uptime(self, attrs): - self.host_info.set_uptime(self._parsing(attrs, [], ["seconds", "lastboot"])) - + self.host_info.set_uptime(self._parsing( + attrs, [], ["seconds", "lastboot"])) def _parse_host_tcpsequence(self, attrs): - self.host_info.set_tcpsequence(self._parsing(attrs, ['difficulty'], ['index', 'values'])) + self.host_info.set_tcpsequence(self._parsing( + attrs, ['difficulty'], ['index', 'values'])) def _parse_host_tcptssequence(self, attrs): - self.host_info.set_tcptssequence(self._parsing(attrs, ['class'], ['values'])) + self.host_info.set_tcptssequence(self._parsing( + attrs, ['class'], ['values'])) def _parse_host_ipidsequence(self, attrs): - self.host_info.set_ipidsequence(self._parsing(attrs, ['class'], ['values'])) + self.host_info.set_ipidsequence(self._parsing( + attrs, ['class'], ['values'])) def _parse_host_trace(self, attrs): trace = {} @@ -1002,7 +1020,6 @@ class NmapParserSAX(ParserBasics, ContentHandler): elif self.in_host and self.in_trace and name == "error": self._parse_host_trace_error(attrs) - def endElement(self, name): if name == "runstats": self.in_interactive_output = False @@ -1052,7 +1069,8 @@ class NmapParserSAX(ParserBasics, ContentHandler): writer = XMLGenerator(f) writer.startDocument() if self.xml_stylesheet_data is not None: - writer.processingInstruction("xml-stylesheet", self.xml_stylesheet_data) + writer.processingInstruction( + "xml-stylesheet", self.xml_stylesheet_data) self._write_nmaprun(writer) self._write_scaninfo(writer) self._write_verbose(writer) @@ -1092,18 +1110,18 @@ class NmapParserSAX(ParserBasics, ContentHandler): ## Finished element writer.startElement("finished", - Attributes(dict(time = str(self.finish_epoc_time), - timestr = time.ctime(time.mktime(self.get_finish_time()))))) + Attributes(dict(time=str(self.finish_epoc_time), + timestr=time.ctime(time.mktime( + self.get_finish_time()))))) writer.endElement("finished") ## Hosts element writer.startElement("hosts", - Attributes(dict(up = str(self.hosts_up), - down = str(self.hosts_down), - total = str(self.hosts_scanned)))) + Attributes(dict(up=str(self.hosts_up), + down=str(self.hosts_down), + total=str(self.hosts_scanned)))) writer.endElement("hosts") - writer.endElement("runstats") # End of Runstats element ######################### @@ -1119,7 +1137,6 @@ class NmapParserSAX(ParserBasics, ContentHandler): Attributes(dict(state=host.state))) writer.endElement("status") - ################## # Address elements ## IPv4 @@ -1148,15 +1165,14 @@ class NmapParserSAX(ParserBasics, ContentHandler): # End of Address elements ######################### - ################### # Hostnames element writer.startElement("hostnames", Attributes({})) for hname in host.hostnames: writer.startElement("hostname", - Attributes(dict(name = hname.get("hostname", ""), - type = hname.get("hostname_type", "")))) + Attributes(dict(name=hname.get("hostname", ""), + type=hname.get("hostname_type", "")))) writer.endElement("hostname") @@ -1164,7 +1180,6 @@ class NmapParserSAX(ParserBasics, ContentHandler): # End of Hostnames element ########################## - ############### # Ports element writer.startElement("ports", Attributes({})) @@ -1172,15 +1187,15 @@ class NmapParserSAX(ParserBasics, ContentHandler): ## Extraports elements for ext in host.get_extraports(): writer.startElement("extraports", - Attributes(dict(count = ext.get("count", ""), - state = ext.get("state", "")))) + Attributes(dict(count=ext.get("count", ""), + state=ext.get("state", "")))) writer.endElement("extraports") ## Port elements for p in host.ports: writer.startElement("port", - Attributes(dict(portid = p.get("portid", ""), - protocol = p.get("protocol", "")))) + Attributes(dict(portid=p.get("portid", ""), + protocol=p.get("protocol", "")))) ### Port state writer.startElement("state", @@ -1208,7 +1223,6 @@ class NmapParserSAX(ParserBasics, ContentHandler): # End of Ports element ###################### - ############ # OS element writer.startElement("os", Attributes({})) @@ -1216,25 +1230,25 @@ class NmapParserSAX(ParserBasics, ContentHandler): ## Ports used elements for pu in host.ports_used: writer.startElement("portused", - Attributes(dict(state = pu.get("state", ""), - proto = pu.get("proto", ""), - portid = pu.get("portid", "")))) + Attributes(dict(state=pu.get("state", ""), + proto=pu.get("proto", ""), + portid=pu.get("portid", "")))) writer.endElement("portused") ## Osmatch elements for om in host.osmatches: writer.startElement("osmatch", - Attributes(dict(name = om.get("name", ""), - accuracy = om.get("accuracy", ""), - line = om.get("line", "")))) + Attributes(dict(name=om.get("name", ""), + accuracy=om.get("accuracy", ""), + line=om.get("line", "")))) ## Osclass elements for oc in om['osclasses']: writer.startElement("osclass", - Attributes(dict(vendor = oc.get("vendor", ""), - osfamily = oc.get("osfamily", ""), - type = oc.get("type", ""), - osgen = oc.get("osgen", ""), - accuracy = oc.get("accuracy", "")))) + Attributes(dict(vendor=oc.get("vendor", ""), + osfamily=oc.get("osfamily", ""), + type=oc.get("type", ""), + osgen=oc.get("osgen", ""), + accuracy=oc.get("accuracy", "")))) writer.endElement("osclass") writer.endElement("osmatch") @@ -1244,8 +1258,8 @@ class NmapParserSAX(ParserBasics, ContentHandler): # Uptime element writer.startElement("uptime", - Attributes(dict(seconds = host.uptime.get("seconds", ""), - lastboot = host.uptime.get("lastboot", "")))) + Attributes(dict(seconds=host.uptime.get("seconds", ""), + lastboot=host.uptime.get("lastboot", "")))) writer.endElement("uptime") ##################### @@ -1253,21 +1267,21 @@ class NmapParserSAX(ParserBasics, ContentHandler): ## TCP Sequence element # Cannot use dict() here, because of the 'class' attribute. writer.startElement("tcpsequence", - Attributes({"index":host.tcpsequence.get("index", ""), - "difficulty":host.tcpsequence.get("difficulty", ""), - "values":host.tcpsequence.get("values", "")})) + Attributes({"index": host.tcpsequence.get("index", ""), + "difficulty": host.tcpsequence.get("difficulty", ""), + "values": host.tcpsequence.get("values", "")})) writer.endElement("tcpsequence") ## IP ID Sequence element writer.startElement("ipidsequence", - Attributes({"class":host.ipidsequence.get("class", ""), - "values":host.ipidsequence.get("values", "")})) + Attributes({"class": host.ipidsequence.get("class", ""), + "values": host.ipidsequence.get("values", "")})) writer.endElement("ipidsequence") ## TCP TS Sequence element writer.startElement("tcptssequence", - Attributes({"class":host.tcptssequence.get("class", ""), - "values":host.tcptssequence.get("values", "")})) + Attributes({"class": host.tcptssequence.get("class", ""), + "values": host.tcptssequence.get("values", "")})) writer.endElement("tcptssequence") # End of sequences elements ########################### @@ -1275,21 +1289,21 @@ class NmapParserSAX(ParserBasics, ContentHandler): ## Trace element if len(host.trace) > 0: writer.startElement("trace", - Attributes({"proto":host.trace.get("proto", ""), - "port":host.trace.get("port", "")})) + Attributes({"proto": host.trace.get("proto", ""), + "port": host.trace.get("port", "")})) if "hops" in host.trace: for hop in host.trace["hops"]: writer.startElement("hop", - Attributes({"ttl":hop["ttl"], - "rtt":hop["rtt"], - "ipaddr":hop["ipaddr"], - "host":hop["host"]})) + Attributes({"ttl": hop["ttl"], + "rtt": hop["rtt"], + "ipaddr": hop["ipaddr"], + "host": hop["host"]})) writer.endElement("hop") if "error" in host.trace: writer.startElement("error", - Attributes({"errorstr":host.trace["error"]})) + Attributes({"errorstr": host.trace["error"]})) writer.endElement("error") writer.endElement("trace") @@ -1312,21 +1326,22 @@ class NmapParserSAX(ParserBasics, ContentHandler): def _write_scaninfo(self, writer): for scan in self.scaninfo: writer.startElement("scaninfo", - Attributes(dict(type = scan.get("type", ""), - protocol = scan.get("protocol", ""), - numservices = scan.get("numservices", ""), - services = scan.get("services", "")))) + Attributes(dict(type=scan.get("type", ""), + protocol=scan.get("protocol", ""), + numservices=scan.get("numservices", ""), + services=scan.get("services", "")))) writer.endElement("scaninfo") def _write_nmaprun(self, writer): writer.startElement("nmaprun", - Attributes(dict(args = str(self.nmap_command), - profile_name = str(self.profile_name), - scanner = str(self.scanner), - start = str(self.start), - startstr = time.ctime(time.mktime(self.get_date())), - version = str(self.scanner_version), - xmloutputversion = str(XML_OUTPUT_VERSION)))) + Attributes(dict(args=str(self.nmap_command), + profile_name=str(self.profile_name), + scanner=str(self.scanner), + start=str(self.start), + startstr=time.ctime( + time.mktime(self.get_date())), + version=str(self.scanner_version), + xmloutputversion=str(XML_OUTPUT_VERSION)))) def set_unsaved(self): self.unsaved = True @@ -1334,6 +1349,7 @@ class NmapParserSAX(ParserBasics, ContentHandler): def is_unsaved(self): return self.unsaved + def nmap_parser_sax(): parser = make_parser() nmap_parser = NmapParserSAX() @@ -1345,6 +1361,7 @@ def nmap_parser_sax(): NmapParser = nmap_parser_sax + if __name__ == '__main__': import sys diff --git a/zenmap/zenmapCore/Paths.py b/zenmap/zenmapCore/Paths.py index 29ad56374..c27567cd1 100644 --- a/zenmap/zenmapCore/Paths.py +++ b/zenmap/zenmapCore/Paths.py @@ -133,6 +133,7 @@ from zenmapCore.Version import VERSION from zenmapCore.Name import APP_NAME from zenmapCore.UmitOptionParser import option_parser + # Find out the prefix under which data files (interface definition XML, # pixmaps, etc.) are stored. This can vary depending on whether we are running # in an executable package and what type of package it is, which we check using @@ -161,6 +162,8 @@ MISC_DIR = join(prefix, "share", APP_NAME, "misc") PIXMAPS_DIR = join(prefix, "share", "zenmap", "pixmaps") DOCS_DIR = join(prefix, "share", APP_NAME, "docs") NMAPDATADIR = join(prefix, "..") + + def get_extra_executable_search_paths(): """Return a list of additional executable search paths as a convenience for platforms where the default PATH is inadequate.""" @@ -170,6 +173,7 @@ def get_extra_executable_search_paths(): return [dirname(sys.executable)] return [] + ####### # Paths class Paths(object): @@ -194,7 +198,8 @@ class Paths(object): def __init__(self): self.user_config_dir = option_parser.get_confdir() - self.user_config_file = os.path.join(self.user_config_dir, base_paths['user_config_file']) + self.user_config_file = os.path.join( + self.user_config_dir, base_paths['user_config_file']) self.config_dir = CONFIG_DIR self.locale_dir = LOCALE_DIR self.pixmaps_dir = PIXMAPS_DIR @@ -207,10 +212,12 @@ class Paths(object): return self.__dict__[name] elif name in self.config_files_list: - return return_if_exists(join(self.user_config_dir, base_paths[name])) + return return_if_exists( + join(self.user_config_dir, base_paths[name])) elif name in self.empty_config_files_list: - return return_if_exists(join(self.user_config_dir, base_paths[name]), True) + return return_if_exists( + join(self.user_config_dir, base_paths[name]), True) elif name in self.misc_files_list: return return_if_exists(join(self.misc_dir, base_paths[name])) @@ -223,15 +230,17 @@ class Paths(object): def __setattr__(self, name, value): self.__dict__[name] = value + def create_dir(path): """Create a directory with os.makedirs without raising an error if the - directory already exists.""" + directory already exists.""" try: os.makedirs(path) except OSError, e: if e.errno != errno.EEXIST: raise + def create_user_config_dir(user_dir, template_dir): """Create a user configuration directory by creating the directory if necessary, then copying all the files from the given template directory, @@ -253,6 +262,7 @@ def create_user_config_dir(user_dir, template_dir): shutil.copyfile(template_filename, user_filename) log.debug(">>> Copy %s to %s." % (template_filename, user_filename)) + def return_if_exists(path, create=False): path = os.path.abspath(path) if os.path.exists(path): diff --git a/zenmap/zenmapCore/RecentScans.py b/zenmap/zenmapCore/RecentScans.py index 1822de2ac..48161e2e6 100644 --- a/zenmap/zenmapCore/RecentScans.py +++ b/zenmap/zenmapCore/RecentScans.py @@ -124,6 +124,7 @@ from os import access, R_OK, W_OK from os.path import dirname from zenmapCore.Paths import Path + class RecentScans(object): def __init__(self): self.temp_list = [] diff --git a/zenmap/zenmapCore/ScriptArgsParser.py b/zenmap/zenmapCore/ScriptArgsParser.py index 9f18b0840..54b7a27aa 100644 --- a/zenmap/zenmapCore/ScriptArgsParser.py +++ b/zenmap/zenmapCore/ScriptArgsParser.py @@ -131,6 +131,7 @@ quoted_re = re.compile(r'\s*(([\'"])(.*?[^\\])\2)\s*([},=]|$)') # "^%s*(['\"])%1%s*[},=]" empty_re = re.compile(r'\s*(([\'"])\2)\s*([},=]|$)') + def parse_string(s, start): """Parses a single string that is quoted, unquoted or empty. It returns the found string along with the next starting position """ @@ -140,6 +141,7 @@ def parse_string(s, start): return m.group(1), m.end(1) raise ValueError("No string found at %s." % repr(s[start:])) + def next_char(s, start): """Returns the next character and position in the string.""" while start < len(s) and s[start].isspace(): @@ -149,6 +151,7 @@ def next_char(s, start): else: return None, start + def parse_value(s, start): """If the string starting from start is a name-value pair, returns a name-value tuple. Otherwise returns a plain string.""" @@ -172,6 +175,7 @@ def parse_value(s, start): else: return s[start:j], j + def parse_table(s, start): """This function is responsible for parsing a table; i.e, a string that starts with '{'. It returns the position where the balancing pair of braces @@ -192,6 +196,7 @@ def parse_table(s, start): if nc == ",": j += 1 + def parse_script_args(s): """Main function responsible for parsing the script args and storing the name-value pairs in a list. If an invalid argument is present it stores the @@ -202,7 +207,8 @@ def parse_script_args(s): while nc is not None: val, j = parse_value(s, j) if type(val) == str: - raise ValueError("Only name-value pairs expected in parse_script_args.") + raise ValueError( + "Only name-value pairs expected in parse_script_args.") else: args.append(val) nc, j = next_char(s, j) @@ -213,6 +219,7 @@ def parse_script_args(s): return None return args + def parse_script_args_dict(raw_argument): """Wrapper function that copies the name-value pairs from a list into a dictionary.""" @@ -221,7 +228,7 @@ def parse_script_args_dict(raw_argument): if args is None: return None for item in args: - if(len(item) == 2): # only key/value pairs are stored + if(len(item) == 2): # only key/value pairs are stored args_dict[item[0]] = item[1] return args_dict @@ -234,7 +241,11 @@ if __name__ == '__main__': ('a={one,{two,{three}}}', [('a', '{one,{two,{three}}}')]), ('a={"quoted}quoted"}', [('a', '{"quoted}quoted"}')]), ('a="unterminated', None), - ('user=foo,pass=",{}=bar",whois={whodb=nofollow+ripe},userdb=C:\\Some\\Path\\To\\File', [('user', 'foo'), ('pass', '",{}=bar"'), ('whois', '{whodb=nofollow+ripe}'), ('userdb', 'C:\\Some\\Path\\To\\File')]), + ('user=foo,pass=",{}=bar",whois={whodb=nofollow+ripe},' + 'userdb=C:\\Some\\Path\\To\\File', + [('user', 'foo'), ('pass', '",{}=bar"'), + ('whois', '{whodb=nofollow+ripe}'), + ('userdb', 'C:\\Some\\Path\\To\\File')]), ) for test, expected in TESTS: @@ -242,7 +253,7 @@ if __name__ == '__main__': print args_dict args = parse_script_args(test) if args == expected: - print "PASS" , test + print "PASS", test continue print "FAIL", test if args is None: diff --git a/zenmap/zenmapCore/ScriptMetadata.py b/zenmap/zenmapCore/ScriptMetadata.py index b91fd8a44..37007ecb9 100644 --- a/zenmap/zenmapCore/ScriptMetadata.py +++ b/zenmap/zenmapCore/ScriptMetadata.py @@ -131,6 +131,7 @@ import sys from zenmapCore.Paths import Path from zenmapCore.UmitLogging import log + class ScriptDB (object): """Class responsible for parsing the script.db file, fetching script names and categories.""" @@ -138,7 +139,8 @@ class ScriptDB (object): "a": "\a", "b": "\b", "f": "\f", "n": "\n", "r": "\r", "t": "\t", "v": "\v", "\\": "\\", "\"": "\"", "'": "'", "0": "\0" } - def __init__(self, script_db_path = None): + + def __init__(self, script_db_path=None): self.unget_buf = "" self.f = open(script_db_path, "r") @@ -162,7 +164,8 @@ class ScriptDB (object): def parse(self): """Parses a script.db entry and returns it as a dictionary. An entry looks like this: - Entry { filename = "afp-brute.nse", categories = { "auth", "intrusive", } } + Entry { filename = "afp-brute.nse", categories = \ + { "auth", "intrusive", } } """ entries = [] while True: @@ -238,7 +241,8 @@ class ScriptDB (object): if not token or token[0] != "string": raise ScriptDBSyntaxError() entry["filename"] = token[1] - self.expect((("delim", ","), ("ident", "categories"), ("delim", "="), ("delim", "{"))) + self.expect((("delim", ","), ("ident", "categories"), + ("delim", "="), ("delim", "{"))) entry["categories"] = [] token = self.token() if token and token[0] == "string": @@ -263,6 +267,7 @@ class ScriptDB (object): def get_entries_list(self): return self.entries_list + def nsedoc_tags_iter(f): in_doc_comment = False tag_name = None @@ -296,6 +301,7 @@ def nsedoc_tags_iter(f): tag_name = None tag_text = None + class ScriptMetadata (object): """Class responsible for parsing all the script information.""" @@ -305,14 +311,15 @@ class ScriptMetadata (object): def __init__(self, filename): self.filename = filename self.categories = [] - self.arguments = [] # Arguments including library arguments. + self.arguments = [] # Arguments including library arguments. self.license = "" self.author = "" self.description = "" self.output = "" self.usage = "" - url = property(lambda self: "http://nmap.org/nsedoc/scripts/" + os.path.splitext(self.filename)[0] + ".html") + url = property(lambda self: "http://nmap.org/nsedoc/scripts/" + "%s.html" % (os.path.splitext(self.filename)[0])) def __init__(self, scripts_dir, nselib_dir): self.scripts_dir = scripts_dir @@ -351,13 +358,16 @@ class ScriptMetadata (object): return contents def get_string_variable(self, filename, varname): - contents = ScriptMetadata.get_file_contents(os.path.join(self.scripts_dir, filename)) + contents = ScriptMetadata.get_file_contents( + os.path.join(self.scripts_dir, filename)) # Short string? - m = re.search(re.escape(varname) + r'\s*=\s*(["\'])(.*?[^\\])\1', contents) + m = re.search( + re.escape(varname) + r'\s*=\s*(["\'])(.*?[^\\])\1', contents) if m: return m.group(2) # Long string? - m = re.search(re.escape(varname) + r'\s*=\s*\[(=*)\[(.*?)\]\1\]', contents, re.S) + m = re.search( + re.escape(varname) + r'\s*=\s*\[(=*)\[(.*?)\]\1\]', contents, re.S) if m: return m.group(2) return None @@ -398,7 +408,7 @@ class ScriptMetadata (object): for tag_name, tag_text in nsedoc_tags_iter(f): m = re.match(r'([\w._-]+)', tag_text) if (tag_name == "arg" or tag_name == "args") and m: - args.append((m.group(1), re.sub(r'^[\w._-]+','',tag_text))) + args.append((m.group(1), re.sub(r'^[\w._-]+', '', tag_text))) return args def get_arguments(self, filename): @@ -444,6 +454,7 @@ class ScriptMetadata (object): self.library_arguments[libname] = self.get_script_args(filepath) self.library_requires[libname] = self.get_requires(filepath) + def get_script_entries(scripts_dir, nselib_dir): """Merge the information obtained so far into one single entry for each script and return it.""" diff --git a/zenmap/zenmapCore/SearchResult.py b/zenmap/zenmapCore/SearchResult.py index d804bf192..8a19a0492 100644 --- a/zenmap/zenmapCore/SearchResult.py +++ b/zenmap/zenmapCore/SearchResult.py @@ -134,6 +134,7 @@ from zenmapCore.NmapOptions import NmapOptions from zenmapCore.NmapParser import NmapParser from zenmapCore.UmitLogging import log + class HostSearch(object): @staticmethod def match_target(host, name): @@ -142,16 +143,20 @@ class HostSearch(object): ip = host.get_ip() ipv6 = host.get_ipv6() - if mac and mac.has_key('addr'): - if name in mac['addr'].lower(): return True - if ip and ip.has_key('addr'): - if name in ip['addr'].lower(): return True - if ipv6 and ipv6.has_key('addr'): - if name in ipv6['addr'].lower(): return True + if mac and 'addr' in mac: + if name in mac['addr'].lower(): + return True + if ip and 'addr' in ip: + if name in ip['addr'].lower(): + return True + if ipv6 and 'addr' in ipv6: + if name in ipv6['addr'].lower(): + return True if HostSearch.match_hostname(host, name): return True return False + @staticmethod def match_hostname(host, hostname): hostname = hostname.lower() @@ -161,20 +166,27 @@ class HostSearch(object): return True else: return False + @staticmethod def match_service(host, service): for port in host.get_ports(): # We concatenate all useful fields and add them to the list - if port['port_state'] not in ['open','open|filtered']: + if port['port_state'] not in ['open', 'open|filtered']: continue - version = port.get("service_name", "") + " " + \ - port.get("service_product", "") + " " + \ - port.get("service_version", "") + " " + \ - port.get("service_extrainfo", "") + version = " ".join( + port.get(x, "") for x in ( + "service_name", + "service_product", + "service_version", + "service_extrainfo" + ) + ) + if service in version.lower(): return True else: return False + @staticmethod def match_os(host, os): os = os.lower() @@ -191,6 +203,7 @@ class HostSearch(object): return True return False + @staticmethod def match_port(host_ports, port, port_state): # Check if the port is parsable, if not return False silently @@ -203,6 +216,7 @@ class HostSearch(object): return False + class SearchResult(object): def __init__(self): """This constructor is always called by SearchResult subclasses.""" @@ -223,8 +237,8 @@ class SearchResult(object): # No match => we discard this scan_result break else: - # All operator-matching functions have returned True, so this scan_result - # satisfies all conditions + # All operator-matching functions have returned True, so this + # scan_result satisfies all conditions yield self.parsed_scan def _match_all_args(self, operator, args): @@ -250,7 +264,8 @@ class SearchResult(object): if keyword == "*" or keyword == "": return True - return keyword.lower() in str(self.parsed_scan.__getattribute__(property)).lower() + return keyword.lower() in str( + self.parsed_scan.__getattribute__(property)).lower() def match_keyword(self, keyword): log.debug("Match keyword: %s" % keyword) @@ -261,7 +276,8 @@ class SearchResult(object): def match_profile(self, profile): log.debug("Match profile: %s" % profile) - log.debug("Comparing: %s == %s ??" % (str(self.parsed_scan.profile_name).lower(), + log.debug("Comparing: %s == %s ??" % ( + str(self.parsed_scan.profile_name).lower(), "*%s*" % profile.lower())) if profile == "*" or profile == "" or \ profile.lower() in str(self.parsed_scan.profile_name).lower(): @@ -274,18 +290,20 @@ class SearchResult(object): if option == "*" or option == "": return True - # NOTE: Option matching treats "_" and "-" the same, just like the optcmp - # function in utils.cc . Also, option matching is case-sensitive. + # NOTE: Option matching treats "_" and "-" the same, just like the + # optcmp function in utils.cc . Also, option matching is + # case-sensitive. option = option.replace("_", "-") ops = NmapOptions() ops.parse_string(self.parsed_scan.get_nmap_command()) if "(" in option and ")" in option: - # The syntax allows matching option arguments as "opt:option_name(value)". - # Since we've received only the "option_name(value)" part, we need to parse it. + # The syntax allows matching option arguments as + # "opt:option_name(value)". Since we've received only the + # "option_name(value)" part, we need to parse it. optname = option[:option.find("(")] - optval = option[option.find("(")+1:option.find(")")] + optval = option[option.find("(") + 1:option.find(")")] val = ops["--" + optname] if val is None: @@ -294,7 +312,8 @@ class SearchResult(object): return False return str(val) == optval or str(val) == optval else: - return ops["--" + option] is not None or ops["-" + option] is not None + return (ops["--" + option] is not None or + ops["-" + option] is not None) def match_date(self, date_arg, operator="date"): # The parsed scan's get_date() returns a time.struct_time, so we @@ -314,15 +333,17 @@ class SearchResult(object): year, month, day = date_arg.split("-") parsed_date = date(int(year), int(month), int(day)) elif re.match("[-|\+]\d+$", date_arg): - # We need to convert from the "-n" format (n days ago) to a date object - # (I found this in some old code, don't ask :) ) - parsed_date = date.fromordinal(date.today().toordinal() + int(date_arg)) + # We need to convert from the "-n" format (n days ago) to a date + # object (I found this in some old code, don't ask :) ) + parsed_date = date.fromordinal( + date.today().toordinal() + int(date_arg)) else: # Fail silently return False - # Now that we have both the scan date and the user date converted to date objects, - # we need to make a comparison based on the operator (date, after, before). + # Now that we have both the scan date and the user date converted to + # date objects, we need to make a comparison based on the operator + # (date, after, before). if operator == "date": return abs((scan_date - parsed_date).days) <= fuzz # We ignore fuzziness for after: and before: @@ -351,10 +372,11 @@ class SearchResult(object): return False def match_os(self, os): - # If you have lots of big scans in your DB (with a lot of hosts scanned), - # you're probably better off using the keyword (freetext) search. Keyword - # search just greps through the nmap output, while this function iterates - # through all parsed OS-related values for every host in every scan! + # If you have lots of big scans in your DB (with a lot of hosts + # scanned), you're probably better off using the keyword (freetext) + # search. Keyword search just greps through the nmap output, while this + # function iterates through all parsed OS-related values for every host + # in every scan! hosts = self.parsed_scan.get_hosts() for host in hosts: if HostSearch.match_os(host, os): @@ -376,12 +398,13 @@ class SearchResult(object): # Make a list of all scanned ports services = [] for scaninfo in self.parsed_scan.get_scaninfo(): - services.append( scaninfo["services"].split(",") ) + services.append(scaninfo["services"].split(",")) - # These two loops iterate over search ports and over scanned ports. As soon as - # the search finds a given port among the scanned ports, it breaks from the services - # loop and continues with the next port in the ports list. If a port isn't - # found in the services list, the function immediately returns False. + # These two loops iterate over search ports and over scanned ports. As + # soon as the search finds a given port among the scanned ports, it + # breaks from the services loop and continues with the next port in the + # ports list. If a port isn't found in the services list, the function + # immediately returns False. for port in ports: for service in services: if "-" in service and \ @@ -394,7 +417,8 @@ class SearchResult(object): else: return False else: - # The ports loop finished for all ports, which means the search was successful. + # The ports loop finished for all ports, which means the search was + # successful. return True def match_port(self, ports, port_state): @@ -405,7 +429,8 @@ class SearchResult(object): for host in self.parsed_scan.get_hosts(): for port in ports: - if not HostSearch.match_port(host.get_ports(), port, port_state): + if not HostSearch.match_port( + host.get_ports(), port, port_state): break else: return True @@ -445,15 +470,16 @@ class SearchResult(object): return True host = host.lower() - # Since the parser doesn't parse traceroute output, we need to cheat and look - # the host up in the Nmap output, in the Traceroute section of the scan. + # Since the parser doesn't parse traceroute output, we need to cheat + # and look the host up in the Nmap output, in the Traceroute section of + # the scan. nmap_out = self.parsed_scan.get_nmap_output() tr_pos = 0 traceroutes = [] # A scan holds one traceroute section per host while tr_pos != -1: - # Find the beginning and the end of the traceroute section, and append - # the substring to the traceroutes list - tr_pos = nmap_out.find("TRACEROUTE", tr_pos+1) + # Find the beginning and the end of the traceroute section, and + # append the substring to the traceroutes list + tr_pos = nmap_out.find("TRACEROUTE", tr_pos + 1) tr_end_pos = nmap_out.find("\n\n", tr_pos) if tr_pos != -1: traceroutes.append(nmap_out[tr_pos:tr_end_pos]) @@ -465,15 +491,18 @@ class SearchResult(object): return False def match_dir(self, dir): - # The dir: operator is handled by the SearchParser class, we ignore it here. + # The dir: operator is handled by the SearchParser class, we ignore it + # here. return True + class SearchDummy(SearchResult): - """A dummy search class that returns no results. It is used as a placeholder - when SearchDB can't be used.""" + """A dummy search class that returns no results. It is used as a + placeholder when SearchDB can't be used.""" def get_scan_results(self): return [] + class SearchDB(SearchResult, object): def __init__(self): SearchResult.__init__(self) @@ -492,13 +521,15 @@ class SearchDB(SearchResult, object): parsed.parse(buffer) buffer.close() except Exception, e: - log.warning(">>> Error loading scan with ID %u from database: %s" % (scan.scans_id, str(e))) + log.warning(">>> Error loading scan with ID %u from database: " + "%s" % (scan.scans_id, str(e))) else: self.scan_results.append(parsed) def get_scan_results(self): return self.scan_results + class SearchDir(SearchResult, object): def __init__(self, search_directory, file_extensions=["usr"]): SearchResult.__init__(self) @@ -510,7 +541,8 @@ class SearchDir(SearchResult, object): elif type(file_extensions) == type([]): self.file_extensions = file_extensions else: - raise Exception("Wrong file extension format! '%s'" % file_extensions) + raise Exception( + "Wrong file extension format! '%s'" % file_extensions) log.debug(">>> Getting directory's scan results") self.scan_results = [] @@ -534,6 +566,7 @@ class SearchDir(SearchResult, object): def get_scan_results(self): return self.scan_results + class SearchResultTest(unittest.TestCase): class SearchClass(SearchResult): """This class is for use by the unit testing code""" @@ -544,6 +577,7 @@ class SearchResultTest(unittest.TestCase): scan = NmapParser() scan.parse_file(filename) self.scan_results.append(scan) + def get_scan_results(self): return self.scan_results @@ -553,31 +587,38 @@ class SearchResultTest(unittest.TestCase): def _test_skeleton(self, key, val): results = [] - search = {key:[val]} + search = {key: [val]} for scan in self.search_result.search(**search): results.append(scan) return len(results) + def test_match_os(self): """Test that checks if the match_os predicate works""" - assert(self._test_skeleton('os','linux') == 2) + assert(self._test_skeleton('os', 'linux') == 2) + def test_match_target(self): """Test that checks if the match_target predicate works""" - assert(self._test_skeleton('target','localhost') == 4) + assert(self._test_skeleton('target', 'localhost') == 4) + def test_match_port_open(self): """Test that checks if the match_open predicate works""" assert(self._test_skeleton('open', '22') == 7) + def test_match_port_closed(self): """Test that checks if the match_closed predicate works""" assert(self._test_skeleton('open', '22') == 7) assert(self._test_skeleton('closed', '22') == 9) + def test_match_service(self): """Test that checks if the match_service predicate works""" assert(self._test_skeleton('service', 'apache') == 9) assert(self._test_skeleton('service', 'openssh') == 7) + def test_match_service_version(self): """Test that checks if the match_service predicate works when """ """checking version""" assert(self._test_skeleton('service', '2.0.52') == 7) + if __name__ == "__main__": unittest.main() diff --git a/zenmap/zenmapCore/StringPool.py b/zenmap/zenmapCore/StringPool.py index 485f9bf35..e4573313b 100644 --- a/zenmap/zenmapCore/StringPool.py +++ b/zenmap/zenmapCore/StringPool.py @@ -121,6 +121,8 @@ # ***************************************************************************/ UNIQUE_STRING_MAP = {} + + def unique(s): """Return a single unique representation of s (unique as to id), letting s be garbage collected.""" diff --git a/zenmap/zenmapCore/TargetList.py b/zenmap/zenmapCore/TargetList.py index 63600cfe7..51ff3c5ae 100644 --- a/zenmap/zenmapCore/TargetList.py +++ b/zenmap/zenmapCore/TargetList.py @@ -124,6 +124,7 @@ from os import access, R_OK, W_OK from os.path import dirname from zenmapCore.Paths import Path + class TargetList(object): def __init__(self): self.temp_list = [] diff --git a/zenmap/zenmapCore/UmitConf.py b/zenmap/zenmapCore/UmitConf.py index 8996c44dc..adc5a1b1b 100644 --- a/zenmap/zenmapCore/UmitConf.py +++ b/zenmap/zenmapCore/UmitConf.py @@ -130,10 +130,10 @@ from zenmapCore.UmitLogging import log from zenmapCore.UmitConfigParser import UmitConfigParser import zenmapCore.I18N -# This is the global configuration parser object that represents the contents of -# zenmap.conf. It should be initialized once by the application. Most -# interaction with the global parser is done by other classes in this file, like -# SearchConfig, that wrap specific configuration sections. +# This is the global configuration parser object that represents the contents +# of zenmap.conf. It should be initialized once by the application. Most +# interaction with the global parser is done by other classes in this file, +# like SearchConfig, that wrap specific configuration sections. config_parser = UmitConfigParser() # Check if running on Maemo @@ -144,9 +144,11 @@ try: except ImportError: pass + def is_maemo(): return MAEMO + class SearchConfig(UmitConfigParser, object): section_name = "search" @@ -245,10 +247,11 @@ class SearchConfig(UmitConfigParser, object): class Profile(UmitConfigParser, object): """This class represents not just one profile, but a whole collection of - them found in a config file such as scan_profiles.usp. The methods therefore - all take an argument that is the name of the profile to work on.""" + them found in a config file such as scan_profiles.usp. The methods + therefore all take an argument that is the name of the profile to work + on.""" - def __init__(self, user_profile = None, *args): + def __init__(self, user_profile=None, *args): UmitConfigParser.__init__(self, *args) if not user_profile: @@ -272,10 +275,10 @@ class Profile(UmitConfigParser, object): return self.set(profile, attribute, value) def add_profile(self, profile_name, **attributes): - """Add a profile with the given name and attributes to the collection of - profiles. If a profile with the same name exists, it is not overwritten, - and the method returns immediately. The backing file for the profiles is - automatically updated.""" + """Add a profile with the given name and attributes to the collection + of profiles. If a profile with the same name exists, it is not + overwritten, and the method returns immediately. The backing file for + the profiles is automatically updated.""" log.debug(">>> Add Profile '%s': %s" % (profile_name, attributes)) @@ -292,8 +295,10 @@ class Profile(UmitConfigParser, object): self.save_changes() def remove_profile(self, profile_name): - try: self.remove_section(profile_name) - except: pass + try: + self.remove_section(profile_name) + except: + pass self.save_changes() def _verify_profile(self, profile_name): @@ -301,16 +306,17 @@ class Profile(UmitConfigParser, object): return False return True + class CommandProfile (Profile, object): """This class is a wrapper around Profile that provides accessors for the attributes of a profile: command and description""" - def __init__(self, user_profile = None): + def __init__(self, user_profile=None): Profile.__init__(self, user_profile) def get_command(self, profile): command_string = self._get_it(profile, 'command') - # Old versions of Zenmap used to append "%s" to commands and use that to - # substitute the target. Ignore it if present. + # Old versions of Zenmap used to append "%s" to commands and use that + # to substitute the target. Ignore it if present. if command_string.endswith("%s"): command_string = command_string[:-len("%s")] return command_string @@ -325,9 +331,9 @@ class CommandProfile (Profile, object): self._set_it(profile, 'description', description) def get_profile(self, profile_name): - return {'profile':profile_name, \ - 'command':self.get_command(profile_name), \ - 'description':self.get_description(profile_name)} + return {'profile': profile_name, \ + 'command': self.get_command(profile_name), \ + 'description': self.get_description(profile_name)} class NmapOutputHighlight(object): @@ -381,10 +387,14 @@ class NmapOutputHighlight(object): tuple_regex = "[\(\[]\s?(\d+)\s?,\s?(\d+)\s?,\s?(\d+)\s?[\)\]]" if isinstance(settings[3], basestring): - settings[3] = [int(t) for t in re.findall(tuple_regex, settings[3])[0]] + settings[3] = [ + int(t) for t in re.findall(tuple_regex, settings[3])[0] + ] if isinstance(settings[4], basestring): - settings[4]= [int(h) for h in re.findall(tuple_regex, settings[4])[0]] + settings[4] = [ + int(h) for h in re.findall(tuple_regex, settings[4])[0] + ] return settings @@ -446,7 +456,8 @@ class NmapOutputHighlight(object): try: enable = config_parser.get("output_highlight", "enable_highlight") except NoSectionError: - config_parser.set("output_highlight", "enable_highlight", str(True)) + config_parser.set( + "output_highlight", "enable_highlight", str(True)) if enable == "False" or enable == "0" or enable == "": return False @@ -454,9 +465,11 @@ class NmapOutputHighlight(object): def set_enable(self, enable): if enable == False or enable == "0" or enable == None or enable == "": - config_parser.set("output_highlight", "enable_highlight", str(False)) + config_parser.set( + "output_highlight", "enable_highlight", str(False)) else: - config_parser.set("output_highlight", "enable_highlight", str(True)) + config_parser.set( + "output_highlight", "enable_highlight", str(True)) date = property(get_date, set_date) hostname = property(get_hostname, set_hostname) @@ -468,56 +481,68 @@ class NmapOutputHighlight(object): details = property(get_details, set_details) enable = property(get_enable, set_enable) - # These settings are made when there is nothing set yet. They set the "factory" \ - # default to highlight colors - default_highlights = {"date":{"bold":str(True), - "italic":str(False), - "underline":str(False), - "text":[0, 0, 0], - "highlight":[65535, 65535, 65535], - "regex":"\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}\s.{1,4}"}, - "hostname":{"bold":str(True), - "italic":str(True), - "underline":str(True), - "text":[0, 111, 65535], - "highlight":[65535, 65535, 65535], - "regex":"(\w{2,}://)*[\w-]{2,}\.[\w-]{2,}(\.[\w-]{2,})*(/[[\w-]{2,}]*)*"}, - "ip":{"bold":str(True), - "italic":str(False), - "underline":str(False), - "text":[0, 0, 0], - "highlight":[65535, 65535, 65535], - "regex":"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"}, - "port_list":{"bold":str(True), - "italic":str(False), - "underline":str(False), - "text":[0, 1272, 28362], - "highlight":[65535, 65535, 65535], - "regex":"PORT\s+STATE\s+SERVICE(\s+VERSION)?[^\n]*"}, - "open_port":{"bold":str(True), - "italic":str(False), - "underline":str(False), - "text":[0, 41036, 2396], - "highlight":[65535, 65535, 65535], - "regex":"\d{1,5}/.{1,5}\s+open\s+.*"}, - "closed_port":{"bold":str(False), - "italic":str(False), - "underline":str(False), - "text":[65535, 0, 0], - "highlight":[65535, 65535, 65535], - "regex":"\d{1,5}/.{1,5}\s+closed\s+.*"}, - "filtered_port":{"bold":str(False), - "italic":str(False), - "underline":str(False), - "text":[38502, 39119, 0], - "highlight":[65535, 65535, 65535], - "regex":"\d{1,5}/.{1,5}\s+filtered\s+.*"}, - "details":{"bold":str(True), - "italic":str(False), - "underline":str(True), - "text":[0, 0, 0], - "highlight":[65535, 65535, 65535], - "regex":"^(\w{2,}[\s]{,3}){,4}:"}} + # These settings are made when there is nothing set yet. They set the + # "factory" default to highlight colors + default_highlights = { + "date": { + "bold": str(True), + "italic": str(False), + "underline": str(False), + "text": [0, 0, 0], + "highlight": [65535, 65535, 65535], + "regex": "\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}\s.{1,4}"}, + "hostname": { + "bold": str(True), + "italic": str(True), + "underline": str(True), + "text": [0, 111, 65535], + "highlight": [65535, 65535, 65535], + "regex": "(\w{2,}://)*[\w-]{2,}\.[\w-]{2,}" + "(\.[\w-]{2,})*(/[[\w-]{2,}]*)*"}, + "ip": { + "bold": str(True), + "italic": str(False), + "underline": str(False), + "text": [0, 0, 0], + "highlight": [65535, 65535, 65535], + "regex": "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"}, + "port_list": { + "bold": str(True), + "italic": str(False), + "underline": str(False), + "text": [0, 1272, 28362], + "highlight": [65535, 65535, 65535], + "regex": "PORT\s+STATE\s+SERVICE(\s+VERSION)?[^\n]*"}, + "open_port": { + "bold": str(True), + "italic": str(False), + "underline": str(False), + "text": [0, 41036, 2396], + "highlight": [65535, 65535, 65535], + "regex": "\d{1,5}/.{1,5}\s+open\s+.*"}, + "closed_port": { + "bold": str(False), + "italic": str(False), + "underline": str(False), + "text": [65535, 0, 0], + "highlight": [65535, 65535, 65535], + "regex": "\d{1,5}/.{1,5}\s+closed\s+.*"}, + "filtered_port": { + "bold": str(False), + "italic": str(False), + "underline": str(False), + "text": [38502, 39119, 0], + "highlight": [65535, 65535, 65535], + "regex": "\d{1,5}/.{1,5}\s+filtered\s+.*"}, + "details": { + "bold": str(True), + "italic": str(False), + "underline": str(True), + "text": [0, 0, 0], + "highlight": [65535, 65535, 65535], + "regex": "^(\w{2,}[\s]{,3}){,4}:"} + } + # Retrieve details from zenmap.conf regarding paths subsection # (e.g. nmap_command_path) - jurand @@ -530,8 +555,9 @@ class PathsConfig(object): def __get_it(self, p_name, default): try: return config_parser.get(self.section_name, p_name) - except (NoOptionError,NoSectionError): - log.debug(">>> Using default \"%s\" for \"%s\"." % (default, p_name)) + except (NoOptionError, NoSectionError): + log.debug( + ">>> Using default \"%s\" for \"%s\"." % (default, p_name)) return default def __set_it(self, property_name, settings): @@ -550,17 +576,22 @@ class PathsConfig(object): self.__set_it("ndiff_command_path", settings) nmap_command_path = property(get_nmap_command_path, set_nmap_command_path) - ndiff_command_path = property(get_ndiff_command_path, set_ndiff_command_path) + ndiff_command_path = property( + get_ndiff_command_path, set_ndiff_command_path) + # Exceptions class ProfileNotFound: - def __init__ (self, profile): + def __init__(self, profile): self.profile = profile - def __str__ (self): - return "No profile named '"+self.profile+"' found!" + + def __str__(self): + return "No profile named '" + self.profile + "' found!" + class ProfileCouldNotBeSaved: - def __init__ (self, profile): + def __init__(self, profile): self.profile = profile - def __str__ (self): - return "Profile named '"+self.profile+"' could not be saved!" + + def __str__(self): + return "Profile named '" + self.profile + "' could not be saved!" diff --git a/zenmap/zenmapCore/UmitConfigParser.py b/zenmap/zenmapCore/UmitConfigParser.py index 90f89fb7c..0a02679f5 100644 --- a/zenmap/zenmapCore/UmitConfigParser.py +++ b/zenmap/zenmapCore/UmitConfigParser.py @@ -121,9 +121,11 @@ # ***************************************************************************/ from os.path import exists -from ConfigParser import ConfigParser, DEFAULTSECT, NoOptionError, NoSectionError +from ConfigParser import ConfigParser, DEFAULTSECT, NoOptionError, \ + NoSectionError from zenmapCore.UmitLogging import log + class UmitConfigParser(ConfigParser): filenames = None fp = None @@ -158,9 +160,11 @@ class UmitConfigParser(ConfigParser): if len(self.filenames) == 1: filename = self.filenames[0] else: - raise ValueError("UmitConfigParser can't handle a list of filenames: %s" % self.filenames) + raise ValueError("UmitConfigParser can't handle a list " + "of filenames: %s" % self.filenames) else: - raise ValueError("UmitConfigParser can't handle a filename of type %s: %s" % (type(self.filenames), self.filenames)) + raise ValueError("UmitConfigParser can't handle a filename of " + "type %s: %s" % (type(self.filenames), self.filenames)) self.write(open(filename, 'w')) elif self.fp: self.write(self.fp) @@ -188,6 +192,7 @@ class UmitConfigParser(ConfigParser): (key, str(value).replace('\n', '\n\t'))) fp.write("\n") + def test_umit_conf_content(filename): parser = ConfigParser() parser.read(filename) diff --git a/zenmap/zenmapCore/UmitDB.py b/zenmap/zenmapCore/UmitDB.py index a48e7cc9c..cd0b42f54 100644 --- a/zenmap/zenmapCore/UmitDB.py +++ b/zenmap/zenmapCore/UmitDB.py @@ -175,8 +175,8 @@ if isinstance(umitdb, str): fs_enc = "UTF-8" umitdb = umitdb.decode(fs_enc) -# pyslite 2.4.0 doesn't handle a unicode database name, though earlier and later -# versions do. Encode to UTF-8 as pysqlite would do internally anyway. +# pyslite 2.4.0 doesn't handle a unicode database name, though earlier and +# later versions do. Encode to UTF-8 as pysqlite would do internally anyway. umitdb = umitdb.encode("UTF-8") connection = sqlite.connect(umitdb) @@ -192,6 +192,7 @@ except AttributeError: # However, text_factory is available only in pysqlite 2.1.0 and later. pass + class Table(object): def __init__(self, table_name): self.table_name = table_name @@ -203,9 +204,11 @@ class Table(object): if self.__getattribute__("_%s" % item_name): return self.__getattribute__("_%s" % item_name) - sql = "SELECT %s FROM %s WHERE %s_id = %s" % (item_name, self.table_name, - self.table_name, - self.__getattribute__(self.table_id)) + sql = "SELECT %s FROM %s WHERE %s_id = %s" % ( + item_name, + self.table_name, + self.table_name, + self.__getattribute__(self.table_id)) self.cursor.execute(sql) @@ -216,9 +219,11 @@ class Table(object): if item_value == self.__getattribute__("_%s" % item_name): return None - sql = "UPDATE %s SET %s = ? WHERE %s_id = %s" % (self.table_name, item_name, - self.table_name, - self.__getattribute__(self.table_id)) + sql = "UPDATE %s SET %s = ? WHERE %s_id = %s" % ( + self.table_name, + item_name, + self.table_name, + self.__getattribute__(self.table_id)) self.cursor.execute(sql, (item_value,)) connection.commit() self.__setattr__("_%s" % item_name, item_value) @@ -247,31 +252,30 @@ class Table(object): self.cursor.execute(sql) return self.cursor.fetchall()[0][0] + class UmitDB(object): def __init__(self): self.cursor = connection.cursor() def create_db(self): - drop_string = ("DROP TABLE scans;",) + drop_string = "DROP TABLE scans;" try: - for d in drop_string: - self.cursor.execute(d) + self.cursor.execute(drop_string) except: connection.rollback() else: connection.commit() + creation_string = """CREATE TABLE scans ( + scans_id INTEGER PRIMARY KEY AUTOINCREMENT, + scan_name TEXT, + nmap_xml_output TEXT, + digest TEXT, + date INTEGER)""" - creation_string = ("""CREATE TABLE scans (scans_id INTEGER PRIMARY KEY AUTOINCREMENT, - scan_name TEXT, - nmap_xml_output TEXT, - digest TEXT, - date INTEGER)""",) - - for c in creation_string: - self.cursor.execute(c) - connection.commit() + self.cursor.execute(creation_string) + connection.commit() def add_scan(self, **kargs): return Scans(**kargs) @@ -289,11 +293,13 @@ class UmitDB(object): def cleanup(self, save_time): log.debug(">>> Cleaning up data base.") log.debug(">>> Removing results olders than %s seconds" % save_time) - self.cursor.execute("SELECT scans_id FROM scans WHERE date < ?", (time() - save_time,)) + self.cursor.execute("SELECT scans_id FROM scans WHERE date < ?", + (time() - save_time,)) for sid in [sid[0] for sid in self.cursor.fetchall()]: log.debug(">>> Removing results with scans_id %s" % sid) - self.cursor.execute("DELETE FROM scans WHERE scans_id = ?", (sid, )) + self.cursor.execute("DELETE FROM scans WHERE scans_id = ?", + (sid, )) else: connection.commit() log.debug(">>> Data base successfully cleaned up!") @@ -310,25 +316,30 @@ class Scans(Table, object): for k in kargs.keys(): if k not in fields: - raise Exception("Wrong table field passed to creation method. '%s'" % k) + raise Exception( + "Wrong table field passed to creation method. " + "'%s'" % k) - if "nmap_xml_output" not in kargs.keys() or not kargs["nmap_xml_output"]: + if ("nmap_xml_output" not in kargs.keys() or + not kargs["nmap_xml_output"]): raise Exception("Can't save result without xml output") - if not self.verify_digest(md5(kargs["nmap_xml_output"]).hexdigest()): + if not self.verify_digest( + md5(kargs["nmap_xml_output"]).hexdigest()): raise Exception("XML output registered already!") self.scans_id = self.insert(**kargs) def verify_digest(self, digest): - self.cursor.execute("SELECT scans_id FROM scans WHERE digest = ?", (digest, )) + self.cursor.execute( + "SELECT scans_id FROM scans WHERE digest = ?", (digest, )) result = self.cursor.fetchall() if result: return False return True def add_host(self, **kargs): - kargs.update({self.table_id:self.scans_id}) + kargs.update({self.table_id: self.scans_id}) return Hosts(**kargs) def get_hosts(self): diff --git a/zenmap/zenmapCore/UmitLogging.py b/zenmap/zenmapCore/UmitLogging.py index 9e03ff31f..41918c5c3 100644 --- a/zenmap/zenmapCore/UmitLogging.py +++ b/zenmap/zenmapCore/UmitLogging.py @@ -127,6 +127,7 @@ from zenmapCore.UmitOptionParser import option_parser LOGLEVEL = option_parser.get_verbose() + class Log(Logger, object): def __init__(self, name, level=0): Logger.__init__(self, name, level) @@ -143,7 +144,6 @@ class Log(Logger, object): def set_formatter(self, fmt): self.__formatter = Formatter(fmt) - format = "%(levelname)s - %(asctime)s - %(message)s" formatter = property(get_formatter, set_formatter, doc="") diff --git a/zenmap/zenmapCore/UmitOptionParser.py b/zenmap/zenmapCore/UmitOptionParser.py index def589658..dce584d6d 100644 --- a/zenmap/zenmapCore/UmitOptionParser.py +++ b/zenmap/zenmapCore/UmitOptionParser.py @@ -128,6 +128,7 @@ from zenmapCore.Version import VERSION import zenmapCore.I18N from zenmapCore.BasePaths import base_paths + class UmitOptionParser(OptionParser): def __init__(self, args=False): OptionParser.__init__(self, version="%%prog %s" % VERSION) @@ -135,10 +136,10 @@ class UmitOptionParser(OptionParser): self.set_usage("%prog [options] [result files]") self.add_option("--confdir", - default = base_paths["user_config_dir"], - dest = "confdir", - metavar = "DIR", - help = _("\ + default=base_paths["user_config_dir"], + dest="confdir", + metavar="DIR", + help=_("\ Use DIR as the user configuration directory. Default: %default")) ## Open Scan Results (GUI) @@ -163,7 +164,8 @@ scan result files.")) default=[], action="callback", callback=self.__nmap_callback, - help=_("Run %s with the specified args.") % NMAP_DISPLAY_NAME) + help=_("Run %s with the specified args." + ) % NMAP_DISPLAY_NAME) ## Execute a profile against a target (GUI) ### Positional args should be taken as targets to feed this scan diff --git a/zenmap/zenmapGUI/About.py b/zenmap/zenmapGUI/About.py index c6c573b5f..3eafd5667 100644 --- a/zenmap/zenmapGUI/About.py +++ b/zenmap/zenmapGUI/About.py @@ -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("%s" % escape(name)) + name_label.set_markup( + '%s' % 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("%s %s" \ -% (escape(APP_DISPLAY_NAME), escape(VERSION))) + label.set_markup( + '%s %s' % ( + escape(APP_DISPLAY_NAME), escape(VERSION))) label.set_selectable(True) self.vbox.pack_start(label) label = gtk.Label() - label.set_markup("%s" \ -% (escape(APP_COPYRIGHT))) + label.set_markup( + '%s' % (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() diff --git a/zenmap/zenmapGUI/App.py b/zenmap/zenmapGUI/App.py index 32071db7c..07f2626ed 100644 --- a/zenmap/zenmapGUI/App.py +++ b/zenmap/zenmapGUI/App.py @@ -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) diff --git a/zenmap/zenmapGUI/BugReport.py b/zenmap/zenmapGUI/BugReport.py index dc553ca91..70ce40c86 100644 --- a/zenmap/zenmapGUI/BugReport.py +++ b/zenmap/zenmapGUI/BugReport.py @@ -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) diff --git a/zenmap/zenmapGUI/CrashReport.py b/zenmap/zenmapGUI/CrashReport.py index b84f86bc9..b9f83c256 100644 --- a/zenmap/zenmapGUI/CrashReport.py +++ b/zenmap/zenmapGUI/CrashReport.py @@ -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 dev@nmap.org \ -mailing list. (More about the list.) \ -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 dev@nmap.org mailing list. ' + '(More about the list.' + ') 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(_("""\ -Copy and email to dev@nmap.org:\ -""")) + self.email_label.set_markup(_('Copy and email to ' + 'dev@nmap.org:')) 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()) diff --git a/zenmap/zenmapGUI/DiffCompare.py b/zenmap/zenmapGUI/DiffCompare.py index 84e38386e..46de6f7d3 100644 --- a/zenmap/zenmapGUI/DiffCompare.py +++ b/zenmap/zenmapGUI/DiffCompare.py @@ -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='%s' % _('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='%s' % _('Cannot open selected file'), - secondary_text=_("This error occurred while trying to open the file:\n%s") % str(e)) + message_format='%s' % _( + '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() diff --git a/zenmap/zenmapGUI/FileChoosers.py b/zenmap/zenmapGUI/FileChoosers.py index 8360fba3e..52e25ea7a 100644 --- a/zenmap/zenmapGUI/FileChoosers.py +++ b/zenmap/zenmapGUI/FileChoosers.py @@ -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, diff --git a/zenmap/zenmapGUI/FilterBar.py b/zenmap/zenmapGUI/FilterBar.py index f6ef04d6e..a8d315632 100644 --- a/zenmap/zenmapGUI/FilterBar.py +++ b/zenmap/zenmapGUI/FilterBar.py @@ -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.""" diff --git a/zenmap/zenmapGUI/Icons.py b/zenmap/zenmapGUI/Icons.py index 6d099264c..5b5e556a9 100644 --- a/zenmap/zenmapGUI/Icons.py +++ b/zenmap/zenmapGUI/Icons.py @@ -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) diff --git a/zenmap/zenmapGUI/MainWindow.py b/zenmap/zenmapGUI/MainWindow.py index f51d87fb3..b9ce3f7c0 100644 --- a/zenmap/zenmapGUI/MainWindow.py +++ b/zenmap/zenmapGUI/MainWindow.py @@ -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 += "\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 += "\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('%s' % _("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('%s' % _("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 diff --git a/zenmap/zenmapGUI/NmapOutputProperties.py b/zenmap/zenmapGUI/NmapOutputProperties.py index 39b42a88f..bc16b54a0 100644 --- a/zenmap/zenmapGUI/NmapOutputProperties.py +++ b/zenmap/zenmapGUI/NmapOutputProperties.py @@ -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("<>") diff --git a/zenmap/zenmapGUI/NmapOutputViewer.py b/zenmap/zenmapGUI/NmapOutputViewer.py index 8123eef19..40fa0b184 100644 --- a/zenmap/zenmapGUI/NmapOutputViewer.py +++ b/zenmap/zenmapGUI/NmapOutputViewer.py @@ -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)) diff --git a/zenmap/zenmapGUI/OptionBuilder.py b/zenmap/zenmapGUI/OptionBuilder.py index 7d28df44e..b62fdf54e 100644 --- a/zenmap/zenmapGUI/OptionBuilder.py +++ b/zenmap/zenmapGUI/OptionBuilder.py @@ -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 diff --git a/zenmap/zenmapGUI/Print.py b/zenmap/zenmapGUI/Print.py index a39d9251e..2da02210e 100644 --- a/zenmap/zenmapGUI/Print.py +++ b/zenmap/zenmapGUI/Print.py @@ -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) diff --git a/zenmap/zenmapGUI/ProfileCombo.py b/zenmap/zenmapGUI/ProfileCombo.py index ed36b4988..29955b5e2 100644 --- a/zenmap/zenmapGUI/ProfileCombo.py +++ b/zenmap/zenmapGUI/ProfileCombo.py @@ -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) diff --git a/zenmap/zenmapGUI/ProfileEditor.py b/zenmap/zenmapGUI/ProfileEditor.py index 478b69797..34b2bc841 100644 --- a/zenmap/zenmapGUI/ProfileEditor.py +++ b/zenmap/zenmapGUI/ProfileEditor.py @@ -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(''+_("Deleting Profile")+'') - text = HIGEntryLabel(_('Your profile is going to be deleted! Click\ - Ok to continue, or Cancel to go back to Profile Editor.')) + alert = HIGEntryLabel('' + _("Deleting Profile") + '') + 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) diff --git a/zenmap/zenmapGUI/ProfileHelp.py b/zenmap/zenmapGUI/ProfileHelp.py index 035707f93..21fef0074 100644 --- a/zenmap/zenmapGUI/ProfileHelp.py +++ b/zenmap/zenmapGUI/ProfileHelp.py @@ -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 diff --git a/zenmap/zenmapGUI/ScanHostDetailsPage.py b/zenmap/zenmapGUI/ScanHostDetailsPage.py index 61870b2ff..d5719155a 100644 --- a/zenmap/zenmapGUI/ScanHostDetailsPage.py +++ b/zenmap/zenmapGUI/ScanHostDetailsPage.py @@ -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(''+_('Host Status')+'') - self.address_expander = gtk.Expander(''+_('Addresses')+'') - self.hostnames_expander = gtk.Expander(''+_('Hostnames')+'') - self.os_expander = gtk.Expander(''+_('Operating System')+'') - self.portsused_expander = gtk.Expander(''+_('Ports used')+'') - self.osclass_expander = gtk.Expander(''+_('OS Classes')+'') - self.tcp_expander = gtk.Expander(''+_('TCP Sequence')+'') - self.ip_expander = gtk.Expander(''+_('IP ID Sequence')+'') - self.tcpts_expander = gtk.Expander(''+_('TCP TS Sequence')+'') - self.comment_expander = gtk.Expander(''+_('Comments')+'') + self.host_status_expander = gtk.Expander( + '' + _('Host Status') + '') + self.address_expander = gtk.Expander('' + _('Addresses') + '') + self.hostnames_expander = gtk.Expander('' + _('Hostnames') + '') + self.os_expander = gtk.Expander('' + _('Operating System') + '') + self.portsused_expander = gtk.Expander( + '' + _('Ports used') + '') + self.osclass_expander = gtk.Expander('' + _('OS Classes') + '') + self.tcp_expander = gtk.Expander('' + _('TCP Sequence') + '') + self.ip_expander = gtk.Expander('' + _('IP ID Sequence') + '') + self.tcpts_expander = gtk.Expander( + '' + _('TCP TS Sequence') + '') + self.comment_expander = gtk.Expander('' + _('Comments') + '') 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) diff --git a/zenmap/zenmapGUI/ScanHostsView.py b/zenmap/zenmapGUI/ScanHostsView.py index 1e6ef0723..d32c83bd3 100644 --- a/zenmap/zenmapGUI/ScanHostsView.py +++ b/zenmap/zenmapGUI/ScanHostsView.py @@ -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 diff --git a/zenmap/zenmapGUI/ScanInterface.py b/zenmap/zenmapGUI/ScanInterface.py index d0b1597c0..f80ba58f6 100644 --- a/zenmap/zenmapGUI/ScanInterface.py +++ b/zenmap/zenmapGUI/ScanInterface.py @@ -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': , '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", _("")) + 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", _("")) + ) 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'))) diff --git a/zenmap/zenmapGUI/ScanNmapOutputPage.py b/zenmap/zenmapGUI/ScanNmapOutputPage.py index e9995510a..50a553d8e 100644 --- a/zenmap/zenmapGUI/ScanNmapOutputPage.py +++ b/zenmap/zenmapGUI/ScanNmapOutputPage.py @@ -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 diff --git a/zenmap/zenmapGUI/ScanOpenPortsPage.py b/zenmap/zenmapGUI/ScanOpenPortsPage.py index 14fd14754..6572062c8 100644 --- a/zenmap/zenmapGUI/ScanOpenPortsPage.py +++ b/zenmap/zenmapGUI/ScanOpenPortsPage.py @@ -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: diff --git a/zenmap/zenmapGUI/ScanRunDetailsPage.py b/zenmap/zenmapGUI/ScanRunDetailsPage.py index 38b1de404..671851524 100644 --- a/zenmap/zenmapGUI/ScanRunDetailsPage.py +++ b/zenmap/zenmapGUI/ScanRunDetailsPage.py @@ -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(""+_("Command Info")+"") + self.command_expander = gtk.Expander( + "" + _("Command Info") + "") 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(""+_("General Info")+"") + self.general_expander = gtk.Expander( + "" + _("General Info") + "") 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('%s - %s' % (_('Scan Info'), scaninfo['type'].capitalize())) + exp = gtk.Expander('%s - %s' % ( + _('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) diff --git a/zenmap/zenmapGUI/ScanScanListPage.py b/zenmap/zenmapGUI/ScanScanListPage.py index 0cdaaefd6..3019ce3ab 100644 --- a/zenmap/zenmapGUI/ScanScanListPage.py +++ b/zenmap/zenmapGUI/ScanScanListPage.py @@ -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() diff --git a/zenmap/zenmapGUI/ScanToolbar.py b/zenmap/zenmapGUI/ScanToolbar.py index 88768a513..b8b532190 100644 --- a/zenmap/zenmapGUI/ScanToolbar.py +++ b/zenmap/zenmapGUI/ScanToolbar.py @@ -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() diff --git a/zenmap/zenmapGUI/ScansListStore.py b/zenmap/zenmapGUI/ScansListStore.py index c9fe91d8a..dc79e8928 100644 --- a/zenmap/zenmapGUI/ScansListStore.py +++ b/zenmap/zenmapGUI/ScansListStore.py @@ -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.""" diff --git a/zenmap/zenmapGUI/ScriptInterface.py b/zenmap/zenmapGUI/ScriptInterface.py index ec6bfaa56..1d495aa72 100644 --- a/zenmap/zenmapGUI/ScriptInterface.py +++ b/zenmap/zenmapGUI/ScriptInterface.py @@ -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= -oX -", and set it up to call the given callback when - finished.""" + "--script-help= -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) diff --git a/zenmap/zenmapGUI/SearchGUI.py b/zenmap/zenmapGUI/SearchGUI.py index 4c1d3aef9..c51b062a6 100644 --- a/zenmap/zenmapGUI/SearchGUI.py +++ b/zenmap/zenmapGUI/SearchGUI.py @@ -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 %s out of %s scans." % \ - (str(matched), str(total))) + self.search_window.set_label_text( + "Matched %s out of %s 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): diff --git a/zenmap/zenmapGUI/SearchWindow.py b/zenmap/zenmapGUI/SearchWindow.py index 5546bbafc..63323967e 100644 --- a/zenmap/zenmapGUI/SearchWindow.py +++ b/zenmap/zenmapGUI/SearchWindow.py @@ -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) diff --git a/zenmap/zenmapGUI/TargetCombo.py b/zenmap/zenmapGUI/TargetCombo.py index 64efea5a9..cf3067229 100644 --- a/zenmap/zenmapGUI/TargetCombo.py +++ b/zenmap/zenmapGUI/TargetCombo.py @@ -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) diff --git a/zenmap/zenmapGUI/TopologyPage.py b/zenmap/zenmapGUI/TopologyPage.py index 39a244145..7eafcfe50 100644 --- a/zenmap/zenmapGUI/TopologyPage.py +++ b/zenmap/zenmapGUI/TopologyPage.py @@ -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(_("""\ diff --git a/zenmap/zenmapGUI/higwidgets/gtkutils.py b/zenmap/zenmapGUI/higwidgets/gtkutils.py index e9e546b5f..192bb21af 100644 --- a/zenmap/zenmapGUI/higwidgets/gtkutils.py +++ b/zenmap/zenmapGUI/higwidgets/gtkutils.py @@ -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') diff --git a/zenmap/zenmapGUI/higwidgets/higboxes.py b/zenmap/zenmapGUI/higwidgets/higboxes.py index 4f7d23f54..8d1edd008 100644 --- a/zenmap/zenmapGUI/higwidgets/higboxes.py +++ b/zenmap/zenmapGUI/higwidgets/higboxes.py @@ -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(" ") diff --git a/zenmap/zenmapGUI/higwidgets/higbuttons.py b/zenmap/zenmapGUI/higwidgets/higbuttons.py index b10ae114f..040ef1760 100644 --- a/zenmap/zenmapGUI/higwidgets/higbuttons.py +++ b/zenmap/zenmapGUI/higwidgets/higbuttons.py @@ -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: diff --git a/zenmap/zenmapGUI/higwidgets/higdialogs.py b/zenmap/zenmapGUI/higwidgets/higdialogs.py index d510b2d3e..abaa35c74 100644 --- a/zenmap/zenmapGUI/higwidgets/higdialogs.py +++ b/zenmap/zenmapGUI/higwidgets/higdialogs.py @@ -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. diff --git a/zenmap/zenmapGUI/higwidgets/higentries.py b/zenmap/zenmapGUI/higwidgets/higentries.py index db1c27404..54fcc88de 100644 --- a/zenmap/zenmapGUI/higwidgets/higentries.py +++ b/zenmap/zenmapGUI/higwidgets/higentries.py @@ -130,6 +130,7 @@ import gtk HIGTextEntry = gtk.Entry + class HIGPasswordEntry(HIGTextEntry): """ An entry that masks its text diff --git a/zenmap/zenmapGUI/higwidgets/higexpanders.py b/zenmap/zenmapGUI/higwidgets/higexpanders.py index 81db0ea86..1900def72 100644 --- a/zenmap/zenmapGUI/higwidgets/higexpanders.py +++ b/zenmap/zenmapGUI/higwidgets/higexpanders.py @@ -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) diff --git a/zenmap/zenmapGUI/higwidgets/higframe.py b/zenmap/zenmapGUI/higwidgets/higframe.py index 452f7378a..c00685031 100644 --- a/zenmap/zenmapGUI/higwidgets/higframe.py +++ b/zenmap/zenmapGUI/higwidgets/higframe.py @@ -130,6 +130,7 @@ __all__ = ['HIGFrame'] import gtk + class HIGFrame(gtk.Frame): """ Frame without border with bold label. diff --git a/zenmap/zenmapGUI/higwidgets/higlabels.py b/zenmap/zenmapGUI/higwidgets/higlabels.py index 0a5aefd94..8b22903db 100644 --- a/zenmap/zenmapGUI/higwidgets/higlabels.py +++ b/zenmap/zenmapGUI/higwidgets/higlabels.py @@ -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. diff --git a/zenmap/zenmapGUI/higwidgets/higlogindialogs.py b/zenmap/zenmapGUI/higwidgets/higlogindialogs.py index 37b2e92ad..ed9827d01 100644 --- a/zenmap/zenmapGUI/higwidgets/higlogindialogs.py +++ b/zenmap/zenmapGUI/higwidgets/higlogindialogs.py @@ -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) diff --git a/zenmap/zenmapGUI/higwidgets/hignotebooks.py b/zenmap/zenmapGUI/higwidgets/hignotebooks.py index be6a7d0f3..5e756ef6d 100644 --- a/zenmap/zenmapGUI/higwidgets/hignotebooks.py +++ b/zenmap/zenmapGUI/higwidgets/hignotebooks.py @@ -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) diff --git a/zenmap/zenmapGUI/higwidgets/higprogressbars.py b/zenmap/zenmapGUI/higwidgets/higprogressbars.py index 5528d8426..68295f7d2 100644 --- a/zenmap/zenmapGUI/higwidgets/higprogressbars.py +++ b/zenmap/zenmapGUI/higwidgets/higprogressbars.py @@ -132,6 +132,7 @@ import gtk from higboxes import HIGHBox + class HIGLabeledProgressBar(HIGHBox): def __init__(self, label=None): HIGHBox.__init__(self) diff --git a/zenmap/zenmapGUI/higwidgets/higscrollers.py b/zenmap/zenmapGUI/higwidgets/higscrollers.py index 48ece882e..3473ef6f0 100644 --- a/zenmap/zenmapGUI/higwidgets/higscrollers.py +++ b/zenmap/zenmapGUI/higwidgets/higscrollers.py @@ -130,6 +130,7 @@ __all__ = ['HIGScrolledWindow'] import gtk + class HIGScrolledWindow(gtk.ScrolledWindow): def __init__(self): gtk.ScrolledWindow.__init__(self) diff --git a/zenmap/zenmapGUI/higwidgets/higspinner.py b/zenmap/zenmapGUI/higwidgets/higspinner.py index 3528ff715..49e574151 100644 --- a/zenmap/zenmapGUI/higwidgets/higspinner.py +++ b/zenmap/zenmapGUI/higwidgets/higspinner.py @@ -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 diff --git a/zenmap/zenmapGUI/higwidgets/higtables.py b/zenmap/zenmapGUI/higwidgets/higtables.py index 3167f85e0..6ddb107f1 100644 --- a/zenmap/zenmapGUI/higwidgets/higtables.py +++ b/zenmap/zenmapGUI/higwidgets/higtables.py @@ -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) diff --git a/zenmap/zenmapGUI/higwidgets/higtextviewers.py b/zenmap/zenmapGUI/higwidgets/higtextviewers.py index 88125603f..ef698b284 100644 --- a/zenmap/zenmapGUI/higwidgets/higtextviewers.py +++ b/zenmap/zenmapGUI/higwidgets/higtextviewers.py @@ -130,6 +130,7 @@ __all__ = ['HIGTextView'] import gtk + class HIGTextView(gtk.TextView): def __init__(self, text=''): gtk.TextView.__init__(self) diff --git a/zenmap/zenmapGUI/higwidgets/higwindows.py b/zenmap/zenmapGUI/higwidgets/higwindows.py index c0aa16b1b..db8dcb866 100644 --- a/zenmap/zenmapGUI/higwidgets/higwindows.py +++ b/zenmap/zenmapGUI/higwidgets/higwindows.py @@ -128,6 +128,7 @@ higwidgets/higwindows.py import gtk + class HIGWindow(gtk.Window): """HIGFied Window""" def __init__(self, type=gtk.WINDOW_TOPLEVEL): diff --git a/zenmap/zenmapGUI/higwidgets/utils.py b/zenmap/zenmapGUI/higwidgets/utils.py index b023ba64a..ec865305d 100644 --- a/zenmap/zenmapGUI/higwidgets/utils.py +++ b/zenmap/zenmapGUI/higwidgets/utils.py @@ -130,6 +130,7 @@ __all__ = ['HIGSpinner'] import gobject + def gobject_register(klass): if gtk_version_minor < 8: gobject.type_register(klass)