class HttpHeadersView(RememberingVPaned): '''Headers + raw payload view.''' def __init__(self, w3af, parentView, editable=False): '''Make object.''' RememberingVPaned.__init__(self, w3af, 'headers_view') self.id = 'HttpHeadersView' self.label = 'Headers' self.startLine = '' self.parentView = parentView self.is_request = True box = gtk.HBox() self._headersStore = gtk.ListStore( gobject.TYPE_STRING, gobject.TYPE_STRING) self._headersTreeview = gtk.TreeView(self._headersStore) # Column for Name renderer = gtk.CellRendererText() renderer.set_property('editable', editable) renderer.connect('edited', self._headerNameEdited, self._headersStore) column = gtk.TreeViewColumn(_('Name'), renderer, text=0) column.set_sort_column_id(0) column.set_resizable(True) self._headersTreeview.append_column(column) # Column for Value renderer = gtk.CellRendererText() renderer.set_property('editable', editable) renderer.set_property('ellipsize', pango.ELLIPSIZE_END) renderer.connect('edited', self._headerValueEdited, self._headersStore) column = gtk.TreeViewColumn(_('Value'), renderer, text=1) column.set_resizable(True) column.set_expand(True) column.set_sort_column_id(1) self._headersTreeview.append_column(column) self._scrolled = gtk.ScrolledWindow() self._scrolled.add(self._headersTreeview) self._scrolled.show_all() box.pack_start(self._scrolled) # Buttons area buttons = [ (gtk.STOCK_GO_UP, self._moveHeaderUp), (gtk.STOCK_GO_DOWN, self._moveHeaderDown), (gtk.STOCK_ADD, self._addHeader), (gtk.STOCK_DELETE, self._deleteHeader) ] buttonBox = gtk.VBox() for button in buttons: b = gtk.Button(stock=button[0]) b.connect("clicked", button[1]) b.show() buttonBox.pack_start(b, False, False) buttonBox.show() if editable: box.pack_start(buttonBox, False, False) box.show() self.add(box) self._raw = HttpEditor(w3af) self._raw.show() self._raw.set_editable(editable) self._raw.set_wrap(True) self._raw.set_highlight_syntax(False) self._raw.set_highlight_current_line(False) self.initial = False if editable: buf = self._raw.get_buffer() buf.connect("changed", self._changed) self.add(self._raw) def _addHeader(self, widget): """Add header to headers.""" i = self._headersStore.append(["", ""]) selection = self._headersTreeview.get_selection() selection.select_iter(i) def _deleteHeader(self, widget): """Delete selected header.""" selection = self._headersTreeview.get_selection() (model, selected) = selection.get_selected() if selected: model.remove(selected) self._changed() def _moveHeaderDown(self, widget): """Move down selected header.""" selection = self._headersTreeview.get_selection() (model, selected) = selection.get_selected() if not selected: return next = model.iter_next(selected) if next: model.swap(selected, next) self._changed() def _moveHeaderUp(self, widget): """Move up selected header.""" selection = self._headersTreeview.get_selection() model, selected = selection.get_selected() if not selected: return path = model.get_path(selected) position = path[-1] if position == 0: return prev_path = list(path)[:-1] prev_path.append(position - 1) prev = model.get_iter(tuple(prev_path)) model.swap(selected, prev) self._changed() def _headerNameEdited(self, cell, path, new_text, model): '''Callback for header's name edited signal.''' model[path][0] = new_text self._changed() def _headerValueEdited(self, cell, path, new_text, model): '''Callback for header's value edited signal.''' model[path][1] = new_text self._changed() def _updateHeadersTab(self, headers): '''Update current headers view part from headers list.''' self._headersStore.clear() for header in headers: self._headersStore.append([header, headers[header]]) def _changed(self, widg=None): '''Synchronize changes with other views (callback).''' if not self.initial: self.parentView.set_object(self.get_object()) self.parentView.synchronize(self.id) def clear(self): '''Clear view.''' self._headersStore.clear() self._raw.clear() self.startLine = '' def highlight(self, text, tag): '''Highlight word in thetext.''' self._raw.highlight(text, tag) def show_object(self, obj): '''Show object in view.''' if self.is_request: self.startLine = obj.get_request_line() self._updateHeadersTab(obj.get_headers()) data = '' if obj.get_data(): data = str(obj.get_data()) self._raw.set_text(data) else: self.startLine = obj.get_status_line() self._updateHeadersTab(obj.get_headers()) self._raw.set_text(obj.get_body()) def get_object(self): '''Return object (request or resoponse).''' head = self.startLine for header in self._headersStore: head += header[0] + ':' + header[1] + CRLF if self.is_request: return HTTPRequestParser(head, self._raw.get_text()) else: raise Exception('HttpResponseParser is not implemented')
class reqResViewer(gtk.VBox): ''' A widget with the request and the response inside. :author: Andres Riancho ([email protected]) :author: Facundo Batista ( [email protected] ) ''' def __init__(self, w3af, enableWidget=None, withManual=True, withFuzzy=True, withCompare=True, withAudit=True, editableRequest=False, editableResponse=False, widgname="default", layout='Tabbed'): super(reqResViewer, self).__init__() self.w3af = w3af # Request self.request = requestPart(self, w3af, enableWidget, editableRequest, widgname=widgname) self.request.show() # Response self.response = responsePart( self, w3af, editableResponse, widgname=widgname) self.response.show() self.layout = layout if layout == 'Tabbed': self._initTabbedLayout() else: self._initSplittedLayout() # Init req toolbox self._initToolBox(withManual, withFuzzy, withCompare, withAudit) self.show() def _initTabbedLayout(self): '''Init Tabbed layout. It's more convenient for quick view.''' nb = gtk.Notebook() nb.show() self.nb = nb self.pack_start(nb, True, True) nb.append_page(self.request, gtk.Label(_("Request"))) nb.append_page(self.response, gtk.Label(_("Response"))) # Info self.info = HttpEditor(self.w3af) self.info.set_editable(False) #self.info.show() nb.append_page(self.info, gtk.Label(_("Info"))) def _initSplittedLayout(self): '''Init Splitted layout. It's more convenient for intercept.''' self._vpaned = RememberingVPaned(self.w3af, 'trap_view') self._vpaned.show() self.pack_start(self._vpaned, True, True) self._vpaned.add(self.request) self._vpaned.add(self.response) def focus_response(self): if self.layout == 'Tabbed': self.nb.set_current_page(1) def focus_request(self): if self.layout == 'Tabbed': self.nb.set_current_page(0) def _initToolBox(self, withManual, withFuzzy, withCompare, withAudit): # Buttons # This import needs to be here in order to avoid an import loop from core.ui.gui.tools.fuzzy_requests import FuzzyRequests from core.ui.gui.tools.manual_requests import ManualRequests hbox = gtk.HBox() if withManual or withFuzzy or withCompare: if withManual: b = SemiStockButton( "", gtk.STOCK_INDEX, _("Send Request to Manual Editor")) b.connect("clicked", self._send_request, ManualRequests) self.request.childButtons.append(b) b.show() hbox.pack_start(b, False, False, padding=2) if withFuzzy: b = SemiStockButton("", gtk.STOCK_PROPERTIES, _("Send Request to Fuzzy Editor")) b.connect("clicked", self._send_request, FuzzyRequests) self.request.childButtons.append(b) b.show() hbox.pack_start(b, False, False, padding=2) if withCompare: b = SemiStockButton("", gtk.STOCK_ZOOM_100, _( "Send Request and Response to Compare Tool")) b.connect("clicked", self._sendReqResp) self.response.childButtons.append(b) b.show() hbox.pack_start(b, False, False, padding=2) # I always can export requests b = SemiStockButton("", gtk.STOCK_COPY, _("Export Request")) b.connect("clicked", self._send_request, export_request) self.request.childButtons.append(b) b.show() hbox.pack_start(b, False, False, padding=2) self.pack_start(hbox, False, False, padding=5) hbox.show() if withAudit: # Add everything I need for the audit request thing: # The button that shows the menu b = SemiStockButton( "", gtk.STOCK_EXECUTE, _("Audit Request with...")) b.connect("button-release-event", self._popupMenu) self.request.childButtons.append(b) b.show() hbox.pack_start(b, False, False, padding=2) # The throbber (hidden!) self.throbber = helpers.Throbber() hbox.pack_start(self.throbber, True, True) self.draw_area = helpers.DrawingAreaStringRepresentation() hbox.pack_end(self.draw_area, False, False) self.pack_start(hbox, False, False, padding=5) hbox.show() def _popupMenu(self, widget, event): '''Show a Audit popup menu.''' _time = event.time # Get the information about the click #requestId = self._lstore[path][0] # Create the popup menu gm = gtk.Menu() plugin_type = "audit" for plugin_name in sorted(self.w3af.plugins.get_plugin_list(plugin_type)): e = gtk.MenuItem(plugin_name) e.connect('activate', self._auditRequest, plugin_name, plugin_type) gm.append(e) # Add a separator gm.append(gtk.SeparatorMenuItem()) # Add a special item e = gtk.MenuItem('All audit plugins') e.connect('activate', self._auditRequest, 'All audit plugins', 'audit_all') gm.append(e) # show gm.show_all() gm.popup(None, None, None, event.button, _time) def _auditRequest(self, menuItem, plugin_name, plugin_type): """ Audit a request using one or more plugins. :param menuItem: The name of the audit plugin, or the 'All audit plugins' wildcard :param plugin_name: The name of the plugin :param plugin_type: The type of plugin :return: None """ # We show a throbber, and start it self.throbber.show() self.throbber.running(True) request = self.request.get_object() # Now I start the analysis of this request in a new thread, # threading game (copied from craftedRequests) event = threading.Event() impact = ThreadedURLImpact(self.w3af, request, plugin_name, plugin_type, event) impact.start() gobject.timeout_add(200, self._impact_done, event, impact) def _impact_done(self, event, impact): # Keep calling this from timeout_add until isSet if not event.isSet(): return True # We stop the throbber, and hide it self.throbber.hide() self.throbber.running(False) # Analyze the impact if impact.ok: # Lets check if we found any vulnerabilities # # TODO: I should actually show ALL THE REQUESTS generated by audit plugins... # not just the ones with vulnerabilities. # for result in impact.result: # TODO: I'm not sure when this is None bug it appeared in Trac bug #167736 if result.get_id() is not None: for itemId in result.get_id(): historyItem = HistoryItem() historyItem.load(itemId) historyItem.update_tag( historyItem.tag + result.plugin_name) historyItem.info = result.get_desc() historyItem.save() else: if impact.exception.__class__ == w3afException: msg = str(impact.exception) elif impact.exception.__class__ == w3afMustStopException: msg = "Stopped sending requests because " + \ str(impact.exception) elif impact.exception.__class__ == w3afMustStopOnUrlError: msg = "Not sending requests because " + str(impact.exception) else: raise impact.exception # We stop the throbber, and hide it self.throbber.hide() self.throbber.running(False) gtk.gdk.threads_enter() helpers.FriendlyExceptionDlg(msg) gtk.gdk.threads_leave() return False def _send_request(self, widg, func): """Sends the texts to the manual or fuzzy request. :param func: where to send the request. """ headers, data = self.request.get_both_texts() func(self.w3af, (headers, data)) def _sendReqResp(self, widg): """Sends the texts to the compare tool.""" headers, data = self.request.get_both_texts() self.w3af.mainwin.commCompareTool((headers, data, self.response.get_object())) def set_sensitive(self, how): """Sets the pane on/off.""" self.request.set_sensitive(how) self.response.set_sensitive(how)
class reqResViewer(gtk.VBox): ''' A widget with the request and the response inside. :author: Andres Riancho ([email protected]) :author: Facundo Batista ( [email protected] ) ''' def __init__(self, w3af, enableWidget=None, withManual=True, withFuzzy=True, withCompare=True, withAudit=True, editableRequest=False, editableResponse=False, widgname="default", layout='Tabbed'): super(reqResViewer, self).__init__() self.w3af = w3af # Request self.request = requestPart(self, w3af, enableWidget, editableRequest, widgname=widgname) self.request.show() # Response self.response = responsePart(self, w3af, editableResponse, widgname=widgname) self.response.show() self.layout = layout if layout == 'Tabbed': self._initTabbedLayout() else: self._initSplittedLayout() # Init req toolbox self._initToolBox(withManual, withFuzzy, withCompare, withAudit) self.show() def _initTabbedLayout(self): '''Init Tabbed layout. It's more convenient for quick view.''' nb = gtk.Notebook() nb.show() self.nb = nb self.pack_start(nb, True, True) nb.append_page(self.request, gtk.Label(_("Request"))) nb.append_page(self.response, gtk.Label(_("Response"))) # Info self.info = HttpEditor(self.w3af) self.info.set_editable(False) #self.info.show() nb.append_page(self.info, gtk.Label(_("Info"))) def _initSplittedLayout(self): '''Init Splitted layout. It's more convenient for intercept.''' self._vpaned = RememberingVPaned(self.w3af, 'trap_view') self._vpaned.show() self.pack_start(self._vpaned, True, True) self._vpaned.add(self.request) self._vpaned.add(self.response) def focus_response(self): if self.layout == 'Tabbed': self.nb.set_current_page(1) def focus_request(self): if self.layout == 'Tabbed': self.nb.set_current_page(0) def _initToolBox(self, withManual, withFuzzy, withCompare, withAudit): # Buttons # This import needs to be here in order to avoid an import loop from core.ui.gui.tools.fuzzy_requests import FuzzyRequests from core.ui.gui.tools.manual_requests import ManualRequests hbox = gtk.HBox() if withManual or withFuzzy or withCompare: if withManual: b = SemiStockButton("", gtk.STOCK_INDEX, _("Send Request to Manual Editor")) b.connect("clicked", self._send_request, ManualRequests) self.request.childButtons.append(b) b.show() hbox.pack_start(b, False, False, padding=2) if withFuzzy: b = SemiStockButton("", gtk.STOCK_PROPERTIES, _("Send Request to Fuzzy Editor")) b.connect("clicked", self._send_request, FuzzyRequests) self.request.childButtons.append(b) b.show() hbox.pack_start(b, False, False, padding=2) if withCompare: b = SemiStockButton( "", gtk.STOCK_ZOOM_100, _("Send Request and Response to Compare Tool")) b.connect("clicked", self._sendReqResp) self.response.childButtons.append(b) b.show() hbox.pack_start(b, False, False, padding=2) # I always can export requests b = SemiStockButton("", gtk.STOCK_COPY, _("Export Request")) b.connect("clicked", self._send_request, export_request) self.request.childButtons.append(b) b.show() hbox.pack_start(b, False, False, padding=2) self.pack_start(hbox, False, False, padding=5) hbox.show() if withAudit: # Add everything I need for the audit request thing: # The button that shows the menu b = SemiStockButton("", gtk.STOCK_EXECUTE, _("Audit Request with...")) b.connect("button-release-event", self._popupMenu) self.request.childButtons.append(b) b.show() hbox.pack_start(b, False, False, padding=2) # The throbber (hidden!) self.throbber = helpers.Throbber() hbox.pack_start(self.throbber, True, True) self.draw_area = helpers.DrawingAreaStringRepresentation() hbox.pack_end(self.draw_area, False, False) self.pack_start(hbox, False, False, padding=5) hbox.show() def _popupMenu(self, widget, event): '''Show a Audit popup menu.''' _time = event.time # Get the information about the click #requestId = self._lstore[path][0] # Create the popup menu gm = gtk.Menu() plugin_type = "audit" for plugin_name in sorted( self.w3af.plugins.get_plugin_list(plugin_type)): e = gtk.MenuItem(plugin_name) e.connect('activate', self._auditRequest, plugin_name, plugin_type) gm.append(e) # Add a separator gm.append(gtk.SeparatorMenuItem()) # Add a special item e = gtk.MenuItem('All audit plugins') e.connect('activate', self._auditRequest, 'All audit plugins', 'audit_all') gm.append(e) # show gm.show_all() gm.popup(None, None, None, event.button, _time) def _auditRequest(self, menuItem, plugin_name, plugin_type): """ Audit a request using one or more plugins. :param menuItem: The name of the audit plugin, or the 'All audit plugins' wildcard :param plugin_name: The name of the plugin :param plugin_type: The type of plugin :return: None """ # We show a throbber, and start it self.throbber.show() self.throbber.running(True) request = self.request.get_object() # Now I start the analysis of this request in a new thread, # threading game (copied from craftedRequests) event = threading.Event() impact = ThreadedURLImpact(self.w3af, request, plugin_name, plugin_type, event) impact.start() gobject.timeout_add(200, self._impact_done, event, impact) def _impact_done(self, event, impact): # Keep calling this from timeout_add until isSet if not event.isSet(): return True # We stop the throbber, and hide it self.throbber.hide() self.throbber.running(False) # Analyze the impact if impact.ok: # Lets check if we found any vulnerabilities # # TODO: I should actually show ALL THE REQUESTS generated by audit plugins... # not just the ones with vulnerabilities. # for result in impact.result: # TODO: I'm not sure when this is None bug it appeared in Trac bug #167736 if result.get_id() is not None: for itemId in result.get_id(): historyItem = HistoryItem() historyItem.load(itemId) historyItem.update_tag(historyItem.tag + result.plugin_name) historyItem.info = result.get_desc() historyItem.save() else: if impact.exception.__class__ == w3afException: msg = str(impact.exception) elif impact.exception.__class__ == w3afMustStopException: msg = "Stopped sending requests because " + \ str(impact.exception) elif impact.exception.__class__ == w3afMustStopOnUrlError: msg = "Not sending requests because " + str(impact.exception) else: raise impact.exception # We stop the throbber, and hide it self.throbber.hide() self.throbber.running(False) gtk.gdk.threads_enter() helpers.FriendlyExceptionDlg(msg) gtk.gdk.threads_leave() return False def _send_request(self, widg, func): """Sends the texts to the manual or fuzzy request. :param func: where to send the request. """ headers, data = self.request.get_both_texts() func(self.w3af, (headers, data)) def _sendReqResp(self, widg): """Sends the texts to the compare tool.""" headers, data = self.request.get_both_texts() self.w3af.mainwin.commCompareTool( (headers, data, self.response.get_object())) def set_sensitive(self, how): """Sets the pane on/off.""" self.request.set_sensitive(how) self.response.set_sensitive(how)
class HttpHeadersView(RememberingVPaned): '''Headers + raw payload view.''' def __init__(self, w3af, parentView, editable=False): '''Make object.''' RememberingVPaned.__init__(self, w3af, 'headers_view') self.id = 'HttpHeadersView' self.label = 'Headers' self.startLine = '' self.parentView = parentView self.is_request = True box = gtk.HBox() self._headersStore = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING) self._headersTreeview = gtk.TreeView(self._headersStore) # Column for Name renderer = gtk.CellRendererText() renderer.set_property('editable', editable) renderer.connect('edited', self._headerNameEdited, self._headersStore) column = gtk.TreeViewColumn(_('Name'), renderer, text=0) column.set_sort_column_id(0) column.set_resizable(True) self._headersTreeview.append_column(column) # Column for Value renderer = gtk.CellRendererText() renderer.set_property('editable', editable) renderer.set_property('ellipsize', pango.ELLIPSIZE_END) renderer.connect('edited', self._headerValueEdited, self._headersStore) column = gtk.TreeViewColumn(_('Value'), renderer, text=1) column.set_resizable(True) column.set_expand(True) column.set_sort_column_id(1) self._headersTreeview.append_column(column) self._scrolled = gtk.ScrolledWindow() self._scrolled.add(self._headersTreeview) self._scrolled.show_all() box.pack_start(self._scrolled) # Buttons area buttons = [(gtk.STOCK_GO_UP, self._moveHeaderUp), (gtk.STOCK_GO_DOWN, self._moveHeaderDown), (gtk.STOCK_ADD, self._addHeader), (gtk.STOCK_DELETE, self._deleteHeader)] buttonBox = gtk.VBox() for button in buttons: b = gtk.Button(stock=button[0]) b.connect("clicked", button[1]) b.show() buttonBox.pack_start(b, False, False) buttonBox.show() if editable: box.pack_start(buttonBox, False, False) box.show() self.add(box) self._raw = HttpEditor(w3af) self._raw.show() self._raw.set_editable(editable) self._raw.set_wrap(True) self._raw.set_highlight_syntax(False) self._raw.set_highlight_current_line(False) self.initial = False if editable: buf = self._raw.get_buffer() buf.connect("changed", self._changed) self.add(self._raw) def _addHeader(self, widget): """Add header to headers.""" i = self._headersStore.append(["", ""]) selection = self._headersTreeview.get_selection() selection.select_iter(i) def _deleteHeader(self, widget): """Delete selected header.""" selection = self._headersTreeview.get_selection() (model, selected) = selection.get_selected() if selected: model.remove(selected) self._changed() def _moveHeaderDown(self, widget): """Move down selected header.""" selection = self._headersTreeview.get_selection() (model, selected) = selection.get_selected() if not selected: return next = model.iter_next(selected) if next: model.swap(selected, next) self._changed() def _moveHeaderUp(self, widget): """Move up selected header.""" selection = self._headersTreeview.get_selection() model, selected = selection.get_selected() if not selected: return path = model.get_path(selected) position = path[-1] if position == 0: return prev_path = list(path)[:-1] prev_path.append(position - 1) prev = model.get_iter(tuple(prev_path)) model.swap(selected, prev) self._changed() def _headerNameEdited(self, cell, path, new_text, model): '''Callback for header's name edited signal.''' model[path][0] = new_text self._changed() def _headerValueEdited(self, cell, path, new_text, model): '''Callback for header's value edited signal.''' model[path][1] = new_text self._changed() def _updateHeadersTab(self, headers): '''Update current headers view part from headers list.''' self._headersStore.clear() for header in headers: self._headersStore.append([header, headers[header]]) def _changed(self, widg=None): '''Synchronize changes with other views (callback).''' if not self.initial: self.parentView.set_object(self.get_object()) self.parentView.synchronize(self.id) def clear(self): '''Clear view.''' self._headersStore.clear() self._raw.clear() self.startLine = '' def highlight(self, text, tag): '''Highlight word in thetext.''' self._raw.highlight(text, tag) def show_object(self, obj): '''Show object in view.''' if self.is_request: self.startLine = obj.get_request_line() self._updateHeadersTab(obj.get_headers()) data = '' if obj.get_data(): data = str(obj.get_data()) self._raw.set_text(data) else: self.startLine = obj.get_status_line() self._updateHeadersTab(obj.get_headers()) self._raw.set_text(obj.get_body()) def get_object(self): '''Return object (request or resoponse).''' head = self.startLine for header in self._headersStore: head += header[0] + ':' + header[1] + CRLF if self.is_request: return HTTPRequestParser(head, self._raw.get_text()) else: raise Exception('HttpResponseParser is not implemented')