Ejemplo n.º 1
0
    def __init__(self,
                 framework,
                 tabwidget,
                 searchControlPlaceholder,
                 parent=None):
        QObject.__init__(self, parent)

        self.framework = framework
        QObject.connect(self, SIGNAL('destroyed(QObject*)'), self._destroyed)

        self.standardPageFactory = StandardPageFactory(self.framework, None,
                                                       self)
        self.headlessPageFactory = HeadlessPageFactory(self.framework, None,
                                                       self)

        self.qlock = QMutex()

        self.scintillaWidgets = set(
        )  # store scintilla widget reference to handle zoom in/zoom out

        self.contentExtractor = self.framework.getContentExtractor()
        self.htmlExtractor = self.contentExtractor.getExtractor('html')
        self.hexDumper = HexDump()

        self.contentTypeMapping = {
            # TODO: complete
            'json': 'javascript',
            'javascript': 'javascript',
            'text/x-js': 'javascript',
            'html': 'html',
            'text/xml': 'xml',
            'text/html': 'html',
            'text/xhtml': 'html',
            'text/css': 'css',
            'text/plain': 'text',
        }
        self.lexerMapping = {
            'text': None,
            'javascript': Qsci.QsciLexerJavaScript,
            'html': Qsci.QsciLexerHTML,
            'xml': Qsci.QsciLexerXML,
            'css': Qsci.QsciLexerCSS,
        }

        self.setup_ui(tabwidget, searchControlPlaceholder)

        self.Data = None
        self.cursor = None
        self.requestResponse = None
        self.framework.subscribe_database_events(self.db_attach,
                                                 self.db_detach)

        self.framework.subscribe_zoom_in(self.zoom_in_scintilla)
        self.framework.subscribe_zoom_out(self.zoom_out_scintilla)
Ejemplo n.º 2
0
    def __init__(self, framework, mainWindow):
        QObject.__init__(self, mainWindow)
        self.framework = framework
        self.mainWindow = mainWindow

        self.hexDump = HexDump()

        self.mainWindow.encodeButton.clicked.connect(self.encode_data)
        self.mainWindow.encodeWrapButton.clicked.connect(self.encode_wrap)
        self.mainWindow.encodeClearButton.clicked.connect(
            self.encode_clear_data)

        self.mainWindow.decodeButton.clicked.connect(self.decode_data)
        self.mainWindow.decodeWrapButton.clicked.connect(self.decode_wrap)
        self.mainWindow.decodeClearButton.clicked.connect(
            self.decode_clear_data)

        self.encoder_tabs = []
        self.decoder_tabs = []
        self.mainTab = QWidget(self.mainWindow.encoderTabWidget)
        self.make_encoder_decoder_display_tab(self.mainTab)
        self.mainWindow.encoderTabWidget.addTab(self.mainTab,
                                                'Encoding/Decoding')
Ejemplo n.º 3
0
    def __init__(self, framework, tabwidget, searchControlPlaceholder, parent = None):
        QObject.__init__(self, parent)

        self.framework = framework
        QObject.connect(self, SIGNAL('destroyed(QObject*)'), self._destroyed)

        self.standardPageFactory = StandardPageFactory(self.framework, None, self)
        self.headlessPageFactory = HeadlessPageFactory(self.framework, None, self)

        self.qlock = QMutex()

        self.scintillaWidgets = set() # store scintilla widget reference to handle zoom in/zoom out

        self.contentExtractor = self.framework.getContentExtractor()
        self.htmlExtractor = self.contentExtractor.getExtractor('html')
        self.hexDumper = HexDump()

        self.contentTypeMapping = {
            # TODO: complete
            'json' : 'javascript',
            'javascript': 'javascript',
            'text/x-js' : 'javascript',
            'html' : 'html',
            'text/xml' : 'xml',
            'text/html' : 'html',
            'text/xhtml' : 'html',
            'text/css' : 'css',
            'text/plain' : 'text',
            }
        self.lexerMapping = {
            'text' : None,
            'javascript' : Qsci.QsciLexerJavaScript,
            'html' : Qsci.QsciLexerHTML,
            'xml' : Qsci.QsciLexerXML,
            'css' : Qsci.QsciLexerCSS,
            }

        self.setup_ui(tabwidget, searchControlPlaceholder)

        self.Data = None
        self.cursor = None
        self.requestResponse = None
        self.framework.subscribe_database_events(self.db_attach, self.db_detach)

        self.framework.subscribe_zoom_in(self.zoom_in_scintilla)
        self.framework.subscribe_zoom_out(self.zoom_out_scintilla)
Ejemplo n.º 4
0
    def __init__(self, framework, mainWindow):
        QObject.__init__(self, mainWindow)
        self.framework = framework
        self.mainWindow = mainWindow

        self.hexDump = HexDump()

        self.mainWindow.encodeButton.clicked.connect(self.encode_data)
        self.mainWindow.encodeWrapButton.clicked.connect(self.encode_wrap)
        self.mainWindow.encodeClearButton.clicked.connect(self.encode_clear_data)

        self.mainWindow.decodeButton.clicked.connect(self.decode_data)
        self.mainWindow.decodeWrapButton.clicked.connect(self.decode_wrap)
        self.mainWindow.decodeClearButton.clicked.connect(self.decode_clear_data)

        self.encoder_tabs = []
        self.decoder_tabs = []
        self.mainTab = QWidget(self.mainWindow.encoderTabWidget)
        self.make_encoder_decoder_display_tab(self.mainTab)
        self.mainWindow.encoderTabWidget.addTab(self.mainTab, 'Encoding/Decoding')
Ejemplo n.º 5
0
class RequestResponseWidget(QObject):
    def __init__(self,
                 framework,
                 tabwidget,
                 searchControlPlaceholder,
                 parent=None):
        QObject.__init__(self, parent)

        self.framework = framework
        QObject.connect(self, SIGNAL('destroyed(QObject*)'), self._destroyed)

        self.standardPageFactory = StandardPageFactory(self.framework, None,
                                                       self)
        self.headlessPageFactory = HeadlessPageFactory(self.framework, None,
                                                       self)

        self.qlock = QMutex()

        self.scintillaWidgets = set(
        )  # store scintilla widget reference to handle zoom in/zoom out

        self.contentExtractor = self.framework.getContentExtractor()
        self.htmlExtractor = self.contentExtractor.getExtractor('html')
        self.hexDumper = HexDump()

        self.contentTypeMapping = {
            # TODO: complete
            'json': 'javascript',
            'javascript': 'javascript',
            'text/x-js': 'javascript',
            'html': 'html',
            'text/xml': 'xml',
            'text/html': 'html',
            'text/xhtml': 'html',
            'text/css': 'css',
            'text/plain': 'text',
        }
        self.lexerMapping = {
            'text': None,
            'javascript': Qsci.QsciLexerJavaScript,
            'html': Qsci.QsciLexerHTML,
            'xml': Qsci.QsciLexerXML,
            'css': Qsci.QsciLexerCSS,
        }

        self.setup_ui(tabwidget, searchControlPlaceholder)

        self.Data = None
        self.cursor = None
        self.requestResponse = None
        self.framework.subscribe_database_events(self.db_attach,
                                                 self.db_detach)

        self.framework.subscribe_zoom_in(self.zoom_in_scintilla)
        self.framework.subscribe_zoom_out(self.zoom_out_scintilla)

    def _destroyed(self):
        self.framework.unsubscribe_zoom_in(self.zoom_in_scintilla)
        self.framework.unsubscribe_zoom_out(self.zoom_out_scintilla)

    def db_attach(self):
        self.Data = self.framework.getDB()
        self.cursor = self.Data.allocate_thread_cursor()
        self.clear()

    def db_detach(self):
        self.close_cursor()
        self.Data = None
        self.clear()

    def close_cursor(self):
        if self.cursor:
            self.cursor.close()
            self.Data.release_thread_cursor(self.cursor)
            self.cursor = None

    def setup_ui(self, tabwidget, searchControlPlaceholder):

        self.tabwidget = tabwidget
        self.searchControlPlaceholder = searchControlPlaceholder

        self.networkAccessManager = self.framework.getNetworkAccessManager()

        if self.searchControlPlaceholder is not None:
            self.searchLayout = self.searchControlPlaceholder.layout()
            if not self.searchLayout or 0 == self.searchLayout:
                self.searchLayout = QVBoxLayout(self.searchControlPlaceholder)
            self.searchLayout.addWidget(
                self.makeSearchWidget(self.searchControlPlaceholder))
            self.searchLayout.addWidget(
                self.makeConfirmedUpdateWidget(self.searchControlPlaceholder))
            self.searchLayout.setSpacing(0)
            self.searchLayout.setContentsMargins(-1, 0, -1, 0)
            self.searchControlPlaceholder.updateGeometry()

        self.requestView = QWidget(tabwidget)
        self.requestView.setObjectName(tabwidget.objectName() + 'Request')
        self.tabwidget.addTab(self.requestView, 'Request')

        self.responseView = QWidget(tabwidget)
        self.responseView.setObjectName(tabwidget.objectName() + 'Response')
        self.tabwidget.addTab(self.responseView, 'Response')

        self.hexBody = QWidget(tabwidget)
        self.hexBody.setObjectName(tabwidget.objectName() + 'HexBody')
        self.hexBodyIndex = self.tabwidget.addTab(self.hexBody, 'Hex Body')

        self.scriptsView = QWidget(tabwidget)
        self.scriptsView.setObjectName(tabwidget.objectName() + 'Scripts')
        self.scriptsTabIndex = self.tabwidget.addTab(self.scriptsView,
                                                     'Scripts')

        self.commentsView = QWidget(tabwidget)
        self.commentsView.setObjectName(tabwidget.objectName() + 'Comments')
        self.tabwidget.addTab(self.commentsView, 'Comments')

        self.linksView = QWidget(tabwidget)
        self.linksView.setObjectName(tabwidget.objectName() + 'Links')
        self.tabwidget.addTab(self.linksView, 'Links')

        self.formsView = QWidget(tabwidget)
        self.formsView.setObjectName(tabwidget.objectName() + 'Forms')
        self.tabwidget.addTab(self.formsView, 'Forms')

        self.renderView = QWidget(tabwidget)
        self.renderView.setObjectName(tabwidget.objectName() + 'Render')
        self.renderTabIndex = self.tabwidget.addTab(self.renderView, 'Render')
        self.tabwidget.currentChanged.connect(self.handle_tab_currentChanged)

        self.generatedSourceView = QWidget(tabwidget)
        self.generatedSourceView.setObjectName(tabwidget.objectName() +
                                               'GeneratedSource')
        self.generatedSourceTabIndex = self.tabwidget.addTab(
            self.generatedSourceView, 'Generated Source')

        self.notesView = QWidget(tabwidget)
        self.notesView.setObjectName(tabwidget.objectName() + 'Notes')
        self.notesTabIndex = self.tabwidget.addTab(self.notesView, 'Notes')

        self.tab_item_widgets = []

        self.vlayout0 = QVBoxLayout(self.requestView)
        self.requestScintilla = Qsci.QsciScintilla(self.requestView)
        self.setScintillaProperties(self.requestScintilla)
        self.vlayout0.addWidget(self.requestScintilla)
        self.tab_item_widgets.append(self.requestScintilla)

        self.vlayout1 = QVBoxLayout(self.responseView)
        self.responseScintilla = Qsci.QsciScintilla(self.responseView)
        self.responseScintilla.setMarginLineNumbers(1, True)
        self.setScintillaProperties(self.responseScintilla)
        self.vlayout1.addWidget(self.responseScintilla)
        self.tab_item_widgets.append(self.responseScintilla)

        self.vlayout2a = QVBoxLayout(self.hexBody)
        self.hexBodyScintilla = Qsci.QsciScintilla(self.hexBody)
        self.hexBodyScintilla.setFont(self.framework.get_monospace_font())
        self.vlayout2a.addWidget(self.hexBodyScintilla)
        self.tab_item_widgets.append(self.hexBodyScintilla)

        self.vlayout2 = QVBoxLayout(self.scriptsView)
        self.scriptsScintilla = Qsci.QsciScintilla(self.scriptsView)
        #        self.scriptsScintilla.setMarginLineNumbers(1, True)
        self.setScintillaProperties(self.scriptsScintilla, 'javascript')
        self.vlayout2.addWidget(self.scriptsScintilla)
        self.tab_item_widgets.append(self.scriptsScintilla)

        self.vlayout3 = QVBoxLayout(self.commentsView)
        self.commentsScintilla = Qsci.QsciScintilla(self.commentsView)
        #        self.commentsScintilla.setMarginLineNumbers(1, True)
        self.setScintillaProperties(self.commentsScintilla, 'html')
        self.vlayout3.addWidget(self.commentsScintilla)
        self.tab_item_widgets.append(self.commentsScintilla)

        self.vlayout4 = QVBoxLayout(self.linksView)
        self.linksScintilla = Qsci.QsciScintilla(self.linksView)
        self.setScintillaProperties(self.linksScintilla)
        self.vlayout4.addWidget(self.linksScintilla)
        self.tab_item_widgets.append(self.linksScintilla)

        self.vlayout5 = QVBoxLayout(self.formsView)
        self.formsScintilla = Qsci.QsciScintilla(self.formsView)
        self.setScintillaProperties(self.formsScintilla, 'html')
        self.vlayout5.addWidget(self.formsScintilla)
        self.tab_item_widgets.append(self.formsScintilla)

        self.vlayout6 = QVBoxLayout(self.renderView)
        self.renderWebView = RenderingWebView(self.framework,
                                              self.standardPageFactory,
                                              self.renderView)
        self.renderWebView.page().setNetworkAccessManager(
            self.networkAccessManager)
        self.renderWebView.loadFinished.connect(
            self.render_handle_loadFinished)
        self.vlayout6.addWidget(self.renderWebView)
        self.tab_item_widgets.append(self.renderWebView)

        self.vlayout7 = QVBoxLayout(self.generatedSourceView)
        self.generatedSourceScintilla = Qsci.QsciScintilla(
            self.generatedSourceView)
        self.generatedSourceWebView = RenderingWebView(
            self.framework, self.headlessPageFactory, self.generatedSourceView)
        self.generatedSourceWebView.page().setNetworkAccessManager(
            self.networkAccessManager)
        self.generatedSourceWebView.loadFinished.connect(
            self.generatedSource_handle_loadFinished)
        self.generatedSourceWebView.setVisible(False)
        self.generatedSourceScintilla.setMarginLineNumbers(1, True)
        self.setScintillaProperties(self.generatedSourceScintilla, 'html')
        self.vlayout7.addWidget(self.generatedSourceWebView)
        self.vlayout7.addWidget(self.generatedSourceScintilla)
        self.tab_item_widgets.append(self.generatedSourceScintilla)

        self.vlayout8 = QVBoxLayout(self.notesView)
        self.notesTextEdit = QTextEdit(self.notesView)
        self.vlayout8.addWidget(self.notesTextEdit)
        self.tab_item_widgets.append(self.notesTextEdit)

        self.clear()

    def setScintillaProperties(self, scintillaWidget, contentType='text'):
        scintillaWidget.setFont(self.framework.get_font())
        scintillaWidget.setWrapMode(1)
        scintillaWidget.zoomTo(self.framework.get_zoom_size())
        # TOOD: set based on line numbers (size is in pixels)
        scintillaWidget.setMarginWidth(1, '1000')
        self.attachLexer(scintillaWidget, contentType)
        self.scintillaWidgets.add(scintillaWidget)

    def zoom_in_scintilla(self):
        for scintillaWidget in self.scintillaWidgets:
            scintillaWidget.zoomIn()

    def zoom_out_scintilla(self):
        for scintillaWidget in self.scintillaWidgets:
            scintillaWidget.zoomOut()

    def makeSearchWidget(self, parentWidget, tooltip='Search the value'):
        # TODO: these should be store in a class variable list to so that they can be cleared...
        self.searchWidget = QWidget(parentWidget)
        self.searchWidget.setContentsMargins(-1, 0, -1, 0)
        self.search_hlayout = QHBoxLayout(self.searchWidget)
        self.search_label = QLabel(self.searchWidget)
        self.search_label.setText('Search: ')
        self.searchLineEdit = QLineEdit(self.searchWidget)
        self.searchLineEdit.setToolTip(tooltip)
        self.search_hlayout.addWidget(self.search_label)
        self.search_hlayout.addWidget(self.searchLineEdit)
        # always supports regex search
        self.searchReCheckBox = QCheckBox(self.searchWidget)
        self.searchReCheckBox.setText('RE')
        self.searchReCheckBox.setToolTip('Use Regular Expression Syntax')
        self.search_hlayout.addWidget(self.searchReCheckBox)
        self.searchFindButton = QPushButton()
        self.searchFindButton.setText('Find')
        QObject.connect(self.searchFindButton, SIGNAL('clicked()'),
                        self.run_search_find)
        QObject.connect(self.searchLineEdit, SIGNAL('returnPressed()'),
                        self.run_search_find)
        self.search_hlayout.addWidget(self.searchFindButton)
        return self.searchWidget

    def run_search_find(self):
        targetWidget = self.tab_item_widgets[self.tabwidget.currentIndex()]
        if isinstance(targetWidget, Qsci.QsciScintilla):
            self.searchScintilla(targetWidget)
        elif isinstance(targetWidget, QtWebKit.QWebView):
            self.searchWebView(targetWidget)
        else:
            self.searchTextEdit(targetWidget)

    def confirmedButtonStateChanged(self, state):
        # self.emit(SIGNAL('confirmedButtonSet(int)'), state)
        if hasattr(self, 'confirmedCheckBox'):
            self.confirmedCheckBox.setChecked(state)

    def makeConfirmedUpdateWidget(self, parentWidget):
        self.confirmedUpdateWidget = QWidget(parentWidget)
        self.confirmedUpdateWidget.setContentsMargins(-1, 0, -1, 0)
        self.confirmed_hlayout = QHBoxLayout(self.confirmedUpdateWidget)
        self.confirmedCheckBox = QCheckBox(parentWidget)
        self.confirmedCheckBox.setText('Confirmed Vulnerable')
        QObject.connect(self.confirmedCheckBox, SIGNAL('stateChanged(int)'),
                        self.confirmedButtonStateChanged)
        self.quickNotesLabel = QLabel(parentWidget)
        self.quickNotesLabel.setText('Quick Notes: ')
        self.quickNotesEdit = QLineEdit(parentWidget)
        self.confirmed_horizontalSpacer = QSpacerItem(40, 20,
                                                      QSizePolicy.Expanding,
                                                      QSizePolicy.Minimum)
        self.updateButton = QPushButton(parentWidget)
        self.updateButton.setText('Update')
        QObject.connect(self.updateButton, SIGNAL('clicked()'),
                        self.handle_updateButton_clicked)
        self.confirmed_hlayout.addWidget(self.confirmedCheckBox)
        self.confirmed_hlayout.addItem(self.confirmed_horizontalSpacer)
        self.confirmed_hlayout.addWidget(self.quickNotesLabel)
        self.confirmed_hlayout.addWidget(self.quickNotesEdit)
        self.confirmed_hlayout.addWidget(self.updateButton)
        return self.confirmedUpdateWidget

    def handle_updateButton_clicked(self):
        if self.responseId is not None:
            quickNotes = str(self.quickNotesEdit.text()).strip()
            notes = str(self.notesTextEdit.toPlainText())
            confirmed = str(self.confirmedCheckBox.isChecked())
            if len(quickNotes) > 0:
                notes = quickNotes + '\n' + notes
            self.Data.update_responses(self.cursor, notes, '', confirmed,
                                       self.responseId)
            self.quickNotesEdit.setText('')
            self.notesTextEdit.setText(notes)
            # update request response state
            self.requestResponse.confirmed = confirmed
            self.requestResponse.notes = notes
            # TODO: update in datamodel

    def searchTextEdit(self, targetWidget):
        # TODO: simulate regex searching
        searchText = self.searchLineEdit.text()
        return targetWidget.find(searchText)

    def searchScintilla(self, targetWidget):
        searchText = self.searchLineEdit.text()
        line, index = targetWidget.getCursorPosition()
        return targetWidget.findFirst(searchText,
                                      self.searchReCheckBox.isChecked(), False,
                                      False, True, True, line, index)

    def searchWebView(self, targetWidget):
        is_re = self.searchReCheckBox.isChecked()
        searchText = self.searchLineEdit.text()
        # TODO: simulate regex search
        targetWidget.findText(
            '', QtWebKit.QWebPage.FindWrapsAroundDocument
            | QtWebKit.QWebPage.HighlightAllOccurrences)
        return targetWidget.findText(
            searchText, QtWebKit.QWebPage.FindWrapsAroundDocument
            | QtWebKit.QWebPage.HighlightAllOccurrences)

    def viewItemSelected(self, index):
        if index and index.isValid():
            obj = index.internalPointer()
            self.fill(obj.Id)

    def clear(self):
        # clear
        self.responseId = None
        self.requestResponse = None
        self.requestScintilla.setText('')
        self.responseScintilla.setText('')
        self.hexBodyScintilla.setText('')
        self.scriptsScintilla.setText('')
        self.commentsScintilla.setText('')
        self.linksScintilla.setText('')
        self.formsScintilla.setText('')
        self.renderWebView.setHtml('')
        self.generatedSourceWebView.setHtml('')
        self.generatedSourceScintilla.setText('')
        self.contentResults = None
        self.notesTextEdit.setPlainText('')
        self.confirmedButtonStateChanged(Qt.Unchecked)

    def set_search_info(self, searchText, isRE):
        self.searchLineEdit.setText(searchText)
        self.searchReCheckBox.setChecked(isRE)

    def fill(self, Id):
        if self.requestResponse and self.requestResponse.Id == Id:
            # already filled
            return

        if self.qlock.tryLock():
            try:
                self.fill_internal(Id)
            finally:
                self.qlock.unlock()

    def fill_internal(self, Id):

        self.clear()

        if not Id:
            return

        self.responseId = Id
        self.requestResponse = self.framework.get_request_response(Id)
        rr = self.requestResponse

        confirmedState = Qt.Unchecked
        if rr.confirmed and rr.confirmed.lower() in ['y', '1', 'true']:
            confirmedState = Qt.Checked
        self.confirmedButtonStateChanged(confirmedState)

        self.requestScintilla.setText(rr.rawRequest)

        self.attachLexer(self.responseScintilla, rr.responseContentType,
                         rr.responseBody)
        self.responseScintilla.setText(
            ContentHelper.convertBytesToDisplayText(rr.rawResponse))
        self.hexBodyScintilla.setText(self.hexDumper.dump(rr.responseBody))
        self.contentResults = self.generateExtractorResults(
            rr.responseHeaders, rr.responseBody, rr.responseUrl, rr.charset)
        self.notesTextEdit.setText(rr.notes)
        self.handle_tab_currentChanged(self.tabwidget.currentIndex())

    def generateExtractorResults(self, headers, body, url, charset):
        rr = self.requestResponse
        scriptsIO, commentsIO, linksIO, formsIO = StringIO(), StringIO(
        ), StringIO(), StringIO()
        try:
            results = rr.results
            if 'html' == rr.baseType:
                # Create content for parsing HTML
                self.htmlExtractor.process(body, url, charset, results)

                self.tabwidget.setTabText(self.scriptsTabIndex, 'Scripts')
                for script in results.scripts:
                    scriptsIO.write('%s\n\n' % self.flat_str(script))

                self.attachLexer(self.commentsScintilla, 'html')
                for comment in results.comments:
                    commentsIO.write('%s\n\n' % self.flat_str(comment))

                for link in results.links:
                    linksIO.write('%s\n' % self.flat_str(link))

                for form in results.forms:
                    formsIO.write('%s\n' % self.flat_str(form))

                for input in results.other_inputs:
                    formsIO.write('%s\n' % self.flat_str(input))

            elif 'javascript' == rr.baseType:

                self.tabwidget.setTabText(self.scriptsTabIndex, 'Strings')
                for script_string in results.strings:
                    scriptsIO.write('%s\n' % self.flat_str(script_string))

                self.attachLexer(self.commentsScintilla, 'javascript')
                for comment in results.comments:
                    commentsIO.write('%s\n' % self.flat_str(comment))

                for link in results.links:
                    linksIO.write('%s\n' % self.flat_str(link))

                for link in results.relative_links:
                    linksIO.write('%s\n' % self.flat_str(link))

        except Exception as e:
            # TODO: log
            self.framework.report_exception(e)

        self.scriptsScintilla.setText(scriptsIO.getvalue())
        self.commentsScintilla.setText(commentsIO.getvalue())
        self.linksScintilla.setText(linksIO.getvalue())
        self.formsScintilla.setText(formsIO.getvalue())

    def flat_str(self, u):
        if bytes == type(u):
            try:
                s = u.decode('utf-8')
            except UnicodeDecodeError:
                s = repr(u)[2:-1].replace('\\r', '').replace('\\n',
                                                             '\n').replace(
                                                                 '\\t', '\t')

            return s
        else:
            # may be object type implementing str
            s = str(u)
            return s

    def attachLexer(self, scintillaWidget, contentType, data=''):
        lexer = self.getLexer(contentType, data)
        if lexer:
            lexerInstance = lexer(scintillaWidget)
            lexerInstance.setFont(self.framework.get_font())
            scintillaWidget.setLexer(lexerInstance)
        else:
            scintillaWidget.setLexer(None)

    def handle_tab_currentChanged(self, index):
        if index == self.renderTabIndex:
            return self.doRenderApply()
        elif index == self.generatedSourceTabIndex:
            return self.doGeneratedSourceApply()
        return False

    def doRenderApply(self):
        rr = self.requestResponse
        if rr and rr.responseUrl:
            self.renderWebView.fill_from_response(rr.responseUrl,
                                                  rr.responseHeaders,
                                                  rr.responseBody,
                                                  rr.responseContentType)
            return True
        return False

    def doGeneratedSourceApply(self):
        rr = self.requestResponse
        if rr and rr.responseUrl and 'html' == rr.baseType:
            self.generatedSourceWebView.fill_from_response(
                rr.responseUrl, rr.responseHeaders, rr.responseBody,
                rr.responseContentType)
            return True
        return False

    def generatedSource_handle_loadFinished(self):
        self.set_generated_source(self.generatedSourceWebView)

    def render_handle_loadFinished(self):
        self.set_generated_source(self.renderWebView)

    def set_generated_source(self, webview):
        # TODO: consider merging frames sources?
        # TODO: consider other optimizations
        if self.requestResponse:
            rr = self.requestResponse
            xhtml = webview.page().mainFrame().documentElement().toOuterXml()
            self.generatedSourceScintilla.setText(xhtml)
            body_bytes = xhtml.encode('utf-8')
            self.generateExtractorResults(rr.responseHeaders, body_bytes,
                                          rr.responseUrl, rr.charset)

    def getLexer(self, contentType, data):
        lexerContentType = self.inferContentType(contentType, data)
        return self.lexerMapping[lexerContentType]

    def inferContentType(self, contentType, data):
        # TODO: scan data for additional info
        # XXX: data -> bytes
        for comp in list(self.contentTypeMapping.keys()):
            if comp in contentType:
                return self.contentTypeMapping[comp]
        return 'text'

    def set_search(self, tabname, searchText):
        if tabname == 'request':
            self.tabwidget.setCurrentIndex(0)
        elif tabname == 'response':
            self.tabwidget.setCurrentIndex(1)
        self.searchLineEdit.setText(searchText)
        self.requestScintilla.findFirst(searchText, False, True, False, True)
        self.responseScintilla.findFirst(searchText, False, True, False, True)
Ejemplo n.º 6
0
class RequestResponseWidget(QObject):
    def __init__(self, framework, tabwidget, searchControlPlaceholder, parent = None):
        QObject.__init__(self, parent)

        self.framework = framework
        QObject.connect(self, SIGNAL('destroyed(QObject*)'), self._destroyed)

        self.standardPageFactory = StandardPageFactory(self.framework, None, self)
        self.headlessPageFactory = HeadlessPageFactory(self.framework, None, self)

        self.qlock = QMutex()

        self.scintillaWidgets = set() # store scintilla widget reference to handle zoom in/zoom out

        self.contentExtractor = self.framework.getContentExtractor()
        self.htmlExtractor = self.contentExtractor.getExtractor('html')
        self.hexDumper = HexDump()

        self.contentTypeMapping = {
            # TODO: complete
            'json' : 'javascript',
            'javascript': 'javascript',
            'text/x-js' : 'javascript',
            'html' : 'html',
            'text/xml' : 'xml',
            'text/html' : 'html',
            'text/xhtml' : 'html',
            'text/css' : 'css',
            'text/plain' : 'text',
            }
        self.lexerMapping = {
            'text' : None,
            'javascript' : Qsci.QsciLexerJavaScript,
            'html' : Qsci.QsciLexerHTML,
            'xml' : Qsci.QsciLexerXML,
            'css' : Qsci.QsciLexerCSS,
            }

        self.setup_ui(tabwidget, searchControlPlaceholder)

        self.Data = None
        self.cursor = None
        self.requestResponse = None
        self.framework.subscribe_database_events(self.db_attach, self.db_detach)

        self.framework.subscribe_zoom_in(self.zoom_in_scintilla)
        self.framework.subscribe_zoom_out(self.zoom_out_scintilla)

    def _destroyed(self):
        self.framework.unsubscribe_zoom_in(self.zoom_in_scintilla)
        self.framework.unsubscribe_zoom_out(self.zoom_out_scintilla)

    def db_attach(self):
        self.Data = self.framework.getDB()
        self.cursor = self.Data.allocate_thread_cursor()
        self.clear()

    def db_detach(self):
        self.close_cursor()
        self.Data = None
        self.clear()

    def close_cursor(self):
        if self.cursor:
            self.cursor.close()
            self.Data.release_thread_cursor(self.cursor)
            self.cursor = None

    def setup_ui(self, tabwidget, searchControlPlaceholder):

        self.tabwidget = tabwidget
        self.searchControlPlaceholder = searchControlPlaceholder

        self.networkAccessManager = self.framework.getNetworkAccessManager()

        if self.searchControlPlaceholder is not None:
            self.searchLayout = self.searchControlPlaceholder.layout()
            if not self.searchLayout or 0 == self.searchLayout:
                self.searchLayout = QVBoxLayout(self.searchControlPlaceholder)
            self.searchLayout.addWidget(self.makeSearchWidget(self.searchControlPlaceholder))
            self.searchLayout.addWidget(self.makeConfirmedUpdateWidget(self.searchControlPlaceholder))
            self.searchLayout.setSpacing(0)
            self.searchLayout.setContentsMargins(-1, 0, -1, 0)
            self.searchControlPlaceholder.updateGeometry()

        self.requestView = QWidget(tabwidget)
        self.requestView.setObjectName(tabwidget.objectName()+'Request')
        self.tabwidget.addTab(self.requestView, 'Request')

        self.responseView = QWidget(tabwidget)
        self.responseView.setObjectName(tabwidget.objectName()+'Response')
        self.tabwidget.addTab(self.responseView, 'Response')

        self.hexBody = QWidget(tabwidget)
        self.hexBody.setObjectName(tabwidget.objectName()+'HexBody')
        self.hexBodyIndex = self.tabwidget.addTab(self.hexBody, 'Hex Body')

        self.scriptsView = QWidget(tabwidget)
        self.scriptsView.setObjectName(tabwidget.objectName()+'Scripts')
        self.scriptsTabIndex = self.tabwidget.addTab(self.scriptsView, 'Scripts')

        self.commentsView = QWidget(tabwidget)
        self.commentsView.setObjectName(tabwidget.objectName()+'Comments')
        self.tabwidget.addTab(self.commentsView, 'Comments')

        self.linksView = QWidget(tabwidget)
        self.linksView.setObjectName(tabwidget.objectName()+'Links')
        self.tabwidget.addTab(self.linksView, 'Links')

        self.formsView = QWidget(tabwidget)
        self.formsView.setObjectName(tabwidget.objectName()+'Forms')
        self.tabwidget.addTab(self.formsView, 'Forms')

        self.renderView = QWidget(tabwidget)
        self.renderView.setObjectName(tabwidget.objectName()+'Render')
        self.renderTabIndex = self.tabwidget.addTab(self.renderView, 'Render')
        self.tabwidget.currentChanged.connect(self.handle_tab_currentChanged)

        self.generatedSourceView = QWidget(tabwidget)
        self.generatedSourceView.setObjectName(tabwidget.objectName()+'GeneratedSource')
        self.generatedSourceTabIndex = self.tabwidget.addTab(self.generatedSourceView, 'Generated Source')

        self.notesView = QWidget(tabwidget)
        self.notesView.setObjectName(tabwidget.objectName()+'Notes')
        self.notesTabIndex = self.tabwidget.addTab(self.notesView, 'Notes')

        self.tab_item_widgets = []

        self.vlayout0 = QVBoxLayout(self.requestView)
        self.requestScintilla = Qsci.QsciScintilla(self.requestView)
        self.setScintillaProperties(self.requestScintilla)
        self.vlayout0.addWidget(self.requestScintilla)
        self.tab_item_widgets.append(self.requestScintilla)

        self.vlayout1 = QVBoxLayout(self.responseView)
        self.responseScintilla = Qsci.QsciScintilla(self.responseView)
        self.responseScintilla.setMarginLineNumbers(1, True)
        self.setScintillaProperties(self.responseScintilla)
        self.vlayout1.addWidget(self.responseScintilla)
        self.tab_item_widgets.append(self.responseScintilla)

        self.vlayout2a = QVBoxLayout(self.hexBody)
        self.hexBodyScintilla = Qsci.QsciScintilla(self.hexBody)
        self.hexBodyScintilla.setFont(self.framework.get_monospace_font())
        self.vlayout2a.addWidget(self.hexBodyScintilla)
        self.tab_item_widgets.append(self.hexBodyScintilla)

        self.vlayout2 = QVBoxLayout(self.scriptsView)
        self.scriptsScintilla = Qsci.QsciScintilla(self.scriptsView)
#        self.scriptsScintilla.setMarginLineNumbers(1, True)
        self.setScintillaProperties(self.scriptsScintilla, 'javascript')
        self.vlayout2.addWidget(self.scriptsScintilla)
        self.tab_item_widgets.append(self.scriptsScintilla)

        self.vlayout3 = QVBoxLayout(self.commentsView)
        self.commentsScintilla = Qsci.QsciScintilla(self.commentsView)
#        self.commentsScintilla.setMarginLineNumbers(1, True)
        self.setScintillaProperties(self.commentsScintilla, 'html')
        self.vlayout3.addWidget(self.commentsScintilla)
        self.tab_item_widgets.append(self.commentsScintilla)

        self.vlayout4 = QVBoxLayout(self.linksView)
        self.linksScintilla = Qsci.QsciScintilla(self.linksView)
        self.setScintillaProperties(self.linksScintilla)
        self.vlayout4.addWidget(self.linksScintilla)
        self.tab_item_widgets.append(self.linksScintilla)

        self.vlayout5 = QVBoxLayout(self.formsView)
        self.formsScintilla = Qsci.QsciScintilla(self.formsView)
        self.setScintillaProperties(self.formsScintilla, 'html')
        self.vlayout5.addWidget(self.formsScintilla)
        self.tab_item_widgets.append(self.formsScintilla)

        self.vlayout6 = QVBoxLayout(self.renderView)
        self.renderWebView = RenderingWebView(self.framework, self.standardPageFactory, self.renderView)
        self.renderWebView.page().setNetworkAccessManager(self.networkAccessManager)
        self.renderWebView.loadFinished.connect(self.render_handle_loadFinished)
        self.vlayout6.addWidget(self.renderWebView)
        self.tab_item_widgets.append(self.renderWebView)

        self.vlayout7 = QVBoxLayout(self.generatedSourceView)
        self.generatedSourceScintilla = Qsci.QsciScintilla(self.generatedSourceView)
        self.generatedSourceWebView = RenderingWebView(self.framework, self.headlessPageFactory, self.generatedSourceView)
        self.generatedSourceWebView.page().setNetworkAccessManager(self.networkAccessManager)
        self.generatedSourceWebView.loadFinished.connect(self.generatedSource_handle_loadFinished)
        self.generatedSourceWebView.setVisible(False)
        self.generatedSourceScintilla.setMarginLineNumbers(1, True)
        self.setScintillaProperties(self.generatedSourceScintilla, 'html')
        self.vlayout7.addWidget(self.generatedSourceWebView)
        self.vlayout7.addWidget(self.generatedSourceScintilla)
        self.tab_item_widgets.append(self.generatedSourceScintilla)

        self.vlayout8 = QVBoxLayout(self.notesView)
        self.notesTextEdit = QTextEdit(self.notesView)
        self.vlayout8.addWidget(self.notesTextEdit)
        self.tab_item_widgets.append(self.notesTextEdit)

        self.clear()

    def setScintillaProperties(self, scintillaWidget, contentType = 'text'):
        scintillaWidget.setFont(self.framework.get_font())
        scintillaWidget.setWrapMode(1)
        scintillaWidget.zoomTo(self.framework.get_zoom_size())
        # TOOD: set based on line numbers (size is in pixels)
        scintillaWidget.setMarginWidth(1, '1000')
        self.attachLexer(scintillaWidget, contentType)
        self.scintillaWidgets.add(scintillaWidget)

    def zoom_in_scintilla(self):
        for scintillaWidget in self.scintillaWidgets:
            scintillaWidget.zoomIn()

    def zoom_out_scintilla(self):
        for scintillaWidget in self.scintillaWidgets:
            scintillaWidget.zoomOut()

    def makeSearchWidget(self, parentWidget, tooltip = 'Search the value'):
        # TODO: these should be store in a class variable list to so that they can be cleared...
        self.searchWidget = QWidget(parentWidget)
        self.searchWidget.setContentsMargins(-1, 0, -1, 0)
        self.search_hlayout = QHBoxLayout(self.searchWidget)
        self.search_label = QLabel(self.searchWidget)
        self.search_label.setText('Search: ')
        self.searchLineEdit = QLineEdit(self.searchWidget)
        self.searchLineEdit.setToolTip(tooltip)
        self.search_hlayout.addWidget(self.search_label)
        self.search_hlayout.addWidget(self.searchLineEdit)
        # always supports regex search
        self.searchReCheckBox = QCheckBox(self.searchWidget)
        self.searchReCheckBox.setText('RE')
        self.searchReCheckBox.setToolTip('Use Regular Expression Syntax')
        self.search_hlayout.addWidget(self.searchReCheckBox)
        self.searchFindButton = QPushButton()
        self.searchFindButton.setText('Find')
        QObject.connect(self.searchFindButton, SIGNAL('clicked()'), self.run_search_find)
        QObject.connect(self.searchLineEdit, SIGNAL('returnPressed()'), self.run_search_find)
        self.search_hlayout.addWidget(self.searchFindButton)
        return self.searchWidget

    def run_search_find(self):
        targetWidget = self.tab_item_widgets[self.tabwidget.currentIndex()]
        if isinstance(targetWidget, Qsci.QsciScintilla):
            self.searchScintilla(targetWidget)
        elif isinstance(targetWidget,  QtWebKit.QWebView):
            self.searchWebView(targetWidget)
        else:
            self.searchTextEdit(targetWidget)

    def confirmedButtonStateChanged(self, state):
        # self.emit(SIGNAL('confirmedButtonSet(int)'), state)
        if hasattr(self, 'confirmedCheckBox'):
            self.confirmedCheckBox.setChecked(state)

    def makeConfirmedUpdateWidget(self, parentWidget):
        self.confirmedUpdateWidget = QWidget(parentWidget)
        self.confirmedUpdateWidget.setContentsMargins(-1, 0, -1, 0)
        self.confirmed_hlayout = QHBoxLayout(self.confirmedUpdateWidget)
        self.confirmedCheckBox = QCheckBox(parentWidget)
        self.confirmedCheckBox.setText('Confirmed Vulnerable')
        QObject.connect(self.confirmedCheckBox, SIGNAL('stateChanged(int)'), self.confirmedButtonStateChanged)
        self.quickNotesLabel = QLabel(parentWidget)
        self.quickNotesLabel.setText('Quick Notes: ')
        self.quickNotesEdit = QLineEdit(parentWidget)
        self.confirmed_horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.updateButton = QPushButton(parentWidget)
        self.updateButton.setText('Update')
        QObject.connect(self.updateButton, SIGNAL('clicked()'), self.handle_updateButton_clicked)
        self.confirmed_hlayout.addWidget(self.confirmedCheckBox)
        self.confirmed_hlayout.addItem(self.confirmed_horizontalSpacer)
        self.confirmed_hlayout.addWidget(self.quickNotesLabel)
        self.confirmed_hlayout.addWidget(self.quickNotesEdit)
        self.confirmed_hlayout.addWidget(self.updateButton)
        return self.confirmedUpdateWidget

    def handle_updateButton_clicked(self):
        if self.responseId is not None:
            quickNotes = str(self.quickNotesEdit.text()).strip()
            notes = str(self.notesTextEdit.toPlainText())
            confirmed = str(self.confirmedCheckBox.isChecked())
            if len(quickNotes) > 0:
                notes = quickNotes + '\n' + notes
            self.Data.update_responses(self.cursor, notes, '', confirmed, self.responseId)
            self.quickNotesEdit.setText('')
            self.notesTextEdit.setText(notes)
            # update request response state
            self.requestResponse.confirmed = confirmed
            self.requestResponse.notes = notes
            # TODO: update in datamodel

    def searchTextEdit(self, targetWidget):
        # TODO: simulate regex searching
        searchText = self.searchLineEdit.text()
        return targetWidget.find(searchText)

    def searchScintilla(self, targetWidget):
        searchText = self.searchLineEdit.text()
        line, index = targetWidget.getCursorPosition()
        return targetWidget.findFirst(searchText, self.searchReCheckBox.isChecked(), False, False, True, True, line, index)

    def searchWebView(self, targetWidget):
        is_re = self.searchReCheckBox.isChecked()
        searchText = self.searchLineEdit.text()
        # TODO: simulate regex search
        targetWidget.findText('', QtWebKit.QWebPage.FindWrapsAroundDocument|QtWebKit.QWebPage.HighlightAllOccurrences)
        return targetWidget.findText(searchText, QtWebKit.QWebPage.FindWrapsAroundDocument|QtWebKit.QWebPage.HighlightAllOccurrences)

    def viewItemSelected(self, index):
        if index and index.isValid():
            obj = index.internalPointer()
            self.fill(obj.Id)

    def clear(self):
        # clear
        self.responseId = None
        self.requestResponse = None
        self.requestScintilla.setText('')
        self.responseScintilla.setText('')
        self.hexBodyScintilla.setText('')
        self.scriptsScintilla.setText('')
        self.commentsScintilla.setText('')
        self.linksScintilla.setText('')
        self.formsScintilla.setText('')
        self.renderWebView.setHtml('')
        self.generatedSourceWebView.setHtml('')
        self.generatedSourceScintilla.setText('')
        self.contentResults = None
        self.notesTextEdit.setPlainText('')
        self.confirmedButtonStateChanged(Qt.Unchecked)

    def set_search_info(self, searchText, isRE):
        self.searchLineEdit.setText(searchText)
        self.searchReCheckBox.setChecked(isRE)

    def fill(self, Id):
        if self.requestResponse and self.requestResponse.Id == Id:
            # already filled
            return

        if self.qlock.tryLock():
            try:
                self.fill_internal(Id)
            finally:
                self.qlock.unlock()

    def fill_internal(self, Id):

        self.clear()

        if not Id:
            return

        self.responseId = Id
        self.requestResponse = self.framework.get_request_response(Id)
        rr = self.requestResponse

        confirmedState = Qt.Unchecked
        if rr.confirmed and rr.confirmed.lower() in ['y', '1', 'true']:
            confirmedState = Qt.Checked
        self.confirmedButtonStateChanged(confirmedState)

        self.requestScintilla.setText(rr.rawRequest)

        self.attachLexer(self.responseScintilla, rr.responseContentType, rr.responseBody)
        self.responseScintilla.setText(ContentHelper.convertBytesToDisplayText(rr.rawResponse))
        self.hexBodyScintilla.setText(self.hexDumper.dump(rr.responseBody))
        self.contentResults = self.generateExtractorResults(rr.responseHeaders, rr.responseBody, rr.responseUrl, rr.charset)
        self.notesTextEdit.setText(rr.notes)
        self.handle_tab_currentChanged(self.tabwidget.currentIndex())

    def generateExtractorResults(self, headers, body, url, charset):
        rr = self.requestResponse
        scriptsIO, commentsIO, linksIO, formsIO = StringIO(), StringIO(), StringIO(), StringIO()
        try:
            results = rr.results
            if 'html' == rr.baseType:
                # Create content for parsing HTML
                self.htmlExtractor.process(body, url, charset, results)

                self.tabwidget.setTabText(self.scriptsTabIndex, 'Scripts')
                for script in results.scripts:
                    scriptsIO.write('%s\n\n' % self.flat_str(script))

                self.attachLexer(self.commentsScintilla, 'html')
                for comment in results.comments:
                    commentsIO.write('%s\n\n' % self.flat_str(comment))

                for link in results.links:
                    linksIO.write('%s\n' % self.flat_str(link))

                for form in results.forms:
                    formsIO.write('%s\n' % self.flat_str(form))

                for input in results.other_inputs:
                    formsIO.write('%s\n' % self.flat_str(input))

            elif 'javascript' == rr.baseType:

                self.tabwidget.setTabText(self.scriptsTabIndex, 'Strings')
                for script_string in results.strings:
                    scriptsIO.write('%s\n' % self.flat_str(script_string))

                self.attachLexer(self.commentsScintilla, 'javascript')
                for comment in results.comments:
                    commentsIO.write('%s\n' % self.flat_str(comment))

                for link in results.links:
                    linksIO.write('%s\n' % self.flat_str(link))

                for link in results.relative_links:
                    linksIO.write('%s\n' % self.flat_str(link))

        except Exception as e:
            # TODO: log 
            self.framework.report_exception(e)

        self.scriptsScintilla.setText(scriptsIO.getvalue())
        self.commentsScintilla.setText(commentsIO.getvalue())
        self.linksScintilla.setText(linksIO.getvalue())
        self.formsScintilla.setText(formsIO.getvalue())

    def flat_str(self, u):
        if bytes == type(u):
            try:
                s = u.decode('utf-8')
            except UnicodeDecodeError:
                s = repr(u)[2:-1].replace('\\r', '').replace('\\n', '\n').replace('\\t', '\t')

            return s
        else:
            # may be object type implementing str
            s = str(u)
            return s

    def attachLexer(self, scintillaWidget, contentType, data = ''):
        lexer = self.getLexer(contentType, data)
        if lexer:
            lexerInstance = lexer(scintillaWidget)
            lexerInstance.setFont(self.framework.get_font())
            scintillaWidget.setLexer(lexerInstance)
        else:
            scintillaWidget.setLexer(None)

    def handle_tab_currentChanged(self, index):
        if index == self.renderTabIndex:
            return self.doRenderApply()
        elif index == self.generatedSourceTabIndex:
            return self.doGeneratedSourceApply()
        return False
        
    def doRenderApply(self):
        rr = self.requestResponse
        if rr and rr.responseUrl:
            self.renderWebView.fill_from_response(rr.responseUrl, rr.responseHeaders, rr.responseBody, rr.responseContentType)
            return True
        return False

    def doGeneratedSourceApply(self):
        rr = self.requestResponse
        if rr and rr.responseUrl and 'html' == rr.baseType:
            self.generatedSourceWebView.fill_from_response(rr.responseUrl, rr.responseHeaders, rr.responseBody, rr.responseContentType)
            return True
        return False

    def generatedSource_handle_loadFinished(self):
        self.set_generated_source(self.generatedSourceWebView)

    def render_handle_loadFinished(self):
        self.set_generated_source(self.renderWebView)

    def set_generated_source(self, webview):
        # TODO: consider merging frames sources?
        # TODO: consider other optimizations
        if self.requestResponse:
            rr = self.requestResponse
            xhtml = webview.page().mainFrame().documentElement().toOuterXml()
            self.generatedSourceScintilla.setText(xhtml)
            body_bytes = xhtml.encode('utf-8')
            self.generateExtractorResults(rr.responseHeaders, body_bytes, rr.responseUrl, rr.charset)

    def getLexer(self, contentType, data):
        lexerContentType = self.inferContentType(contentType, data)
        return self.lexerMapping[lexerContentType]
        
    def inferContentType(self, contentType, data):
        # TODO: scan data for additional info
        # XXX: data -> bytes
        for comp in list(self.contentTypeMapping.keys()):
            if comp in contentType:
                return self.contentTypeMapping[comp]
        return 'text'
            
    def set_search(self, tabname, searchText):
        if tabname == 'request':
            self.tabwidget.setCurrentIndex(0)
        elif tabname=='response':
            self.tabwidget.setCurrentIndex(1)
        self.searchLineEdit.setText(searchText)
        self.requestScintilla.findFirst(searchText, False, True, False, True)
        self.responseScintilla.findFirst(searchText, False, True, False, True)
Ejemplo n.º 7
0
class EncoderTab(QObject):
    def __init__(self, framework, mainWindow):
        QObject.__init__(self, mainWindow)
        self.framework = framework
        self.mainWindow = mainWindow

        self.hexDump = HexDump()

        self.mainWindow.encodeButton.clicked.connect(self.encode_data)
        self.mainWindow.encodeWrapButton.clicked.connect(self.encode_wrap)
        self.mainWindow.encodeClearButton.clicked.connect(
            self.encode_clear_data)

        self.mainWindow.decodeButton.clicked.connect(self.decode_data)
        self.mainWindow.decodeWrapButton.clicked.connect(self.decode_wrap)
        self.mainWindow.decodeClearButton.clicked.connect(
            self.decode_clear_data)

        self.encoder_tabs = []
        self.decoder_tabs = []
        self.mainTab = QWidget(self.mainWindow.encoderTabWidget)
        self.make_encoder_decoder_display_tab(self.mainTab)
        self.mainWindow.encoderTabWidget.addTab(self.mainTab,
                                                'Encoding/Decoding')

    def make_encoder_decoder_display_tab(self, parentWidget):
        currentWidget = parentWidget
        vbox_layout = QVBoxLayout(currentWidget)

        encoderTabWidget = QTabWidget(currentWidget)
        decoderTabWidget = QTabWidget(currentWidget)

        # TODO: finish making this dynamically expandable
        self.encoderTextEdit, self.encoderHexEdit = self.make_text_hex_tab(
            encoderTabWidget)
        self.decoderTextEdit, self.decoderHexEdit = self.make_text_hex_tab(
            decoderTabWidget)

        vbox_layout.addWidget(encoderTabWidget)
        vbox_layout.addWidget(decoderTabWidget)

        encoderTabWidget.currentChanged.connect(self.encoder_tab_change)
        decoderTabWidget.currentChanged.connect(self.decoder_tab_change)

        self.encoder_tabs.append(encoderTabWidget)
        self.decoder_tabs.append(decoderTabWidget)

    def make_text_hex_tab(self, currentWidget):

        thisTabWidget = currentWidget

        textTab = QWidget(thisTabWidget)
        thisTabWidget.addTab(textTab, 'Text')
        hexTab = QWidget(thisTabWidget)
        thisTabWidget.addTab(hexTab, 'Hex')

        vlayout_text = QVBoxLayout(textTab)
        thisTextEdit = QTextEdit(textTab)
        vlayout_text.addWidget(thisTextEdit)

        vlayout_hex = QVBoxLayout(hexTab)
        thisHexEdit = Qsci.QsciScintilla(hexTab)
        ScintillaHelpers.SetScintillaProperties(self.framework, thisHexEdit,
                                                'monospace')

        vlayout_hex.addWidget(thisHexEdit)

        return (thisTextEdit, thisHexEdit)

    def encode_data(self):
        """ Encode the specified value """
        tabInstance = self.encoder_tabs[
            self.mainWindow.encoderTabWidget.currentIndex()]
        if 0 == tabInstance.currentIndex():
            # read from text
            encode_value = self.encoderTextEdit.toPlainText()
        elif 1 == tabInstance.currentIndex():
            # read from hex
            encode_value = self.hexDump.undump(self.encoderHexEdit.text())
        encode_method = self.mainWindow.encodingMethodCombo.currentText()
        value = encoderlib.encode_values(encode_value, encode_method)
        self.decoderTextEdit.setPlainText(value)
        self.decoderHexEdit.setText(self.hexDump.dump(value.encode('utf-8')))

    def encode_wrap(self):
        """ Wrap the specified values in the encode window """

        encode_value = str(self.encoderTextEdit.toPlainText())
        wrap_value = self.mainWindow.encodingWrapCombo.currentText()
        value = encoderlib.wrap_encode(encode_value, wrap_value)
        self.encoderTextEdit.setPlainText(value)

    def encode_clear_data(self):
        self.encoderTextEdit.setPlainText('')
        self.encoderHexEdit.setText('')

    def decode_data(self):
        """ Decode the specified value from the decoder interface """
        decode_value = str(self.decoderTextEdit.toPlainText())
        decode_method = self.mainWindow.decodeMethodCombo.currentText()
        value = encoderlib.decode_values(decode_value, decode_method)
        if isinstance(value, bytes):
            self.encoderTextEdit.setPlainText(value.decode('utf-8', 'replace'))
            self.encoderHexEdit.setText(self.hexDump.dump(value))
        else:
            self.encoderTextEdit.setPlainText(value)
            self.encoderHexEdit.setText(
                self.hexDump.dump(value.encode('utf-8')))

    def decode_wrap(self):
        """ Wrap the specified values in the decode window """
        decode_value = str(self.decoderTextEdit.toPlainText())
        wrap_value = self.mainWindow.decodeWrapCombo.currentText()
        value = encoderlib.wrap_decode(decode_value, wrap_value)
        self.decoderTextEdit.setPlainText(value)

    def decode_clear_data(self):
        self.decoderTextEdit.setPlainText('')
        self.decoderHexEdit.setText('')

    def encoder_tab_change(self, index):
        self.handle_text_hex_tab_switch(index, self.encoderTextEdit,
                                        self.encoderHexEdit)

    def decoder_tab_change(self, index):
        self.handle_text_hex_tab_switch(index, self.decoderTextEdit,
                                        self.decoderHexEdit)

    def handle_text_hex_tab_switch(self, index, textEdit, hexEdit):
        # TODO: make this dynamic instead of depending on hard-coded values
        currentIndex = self.mainWindow.encoderTabWidget.currentIndex()
        if 0 == currentIndex:
            if 0 == index:
                # Going to Text
                value = hexEdit.text()
                if value:
                    data = self.hexDump.undump(value)
                    textEdit.setPlainText((data.decode('utf-8', 'replace')))
            elif 1 == index:
                value = textEdit.toPlainText()
                if value:
                    hexEdit.setText(self.hexDump.dump(value.encode('utf-8')))
Ejemplo n.º 8
0
class EncoderTab(QObject):
    def __init__(self, framework, mainWindow):
        QObject.__init__(self, mainWindow)
        self.framework = framework
        self.mainWindow = mainWindow

        self.hexDump = HexDump()

        self.mainWindow.encodeButton.clicked.connect(self.encode_data)
        self.mainWindow.encodeWrapButton.clicked.connect(self.encode_wrap)
        self.mainWindow.encodeClearButton.clicked.connect(self.encode_clear_data)

        self.mainWindow.decodeButton.clicked.connect(self.decode_data)
        self.mainWindow.decodeWrapButton.clicked.connect(self.decode_wrap)
        self.mainWindow.decodeClearButton.clicked.connect(self.decode_clear_data)

        self.encoder_tabs = []
        self.decoder_tabs = []
        self.mainTab = QWidget(self.mainWindow.encoderTabWidget)
        self.make_encoder_decoder_display_tab(self.mainTab)
        self.mainWindow.encoderTabWidget.addTab(self.mainTab, 'Encoding/Decoding')

    def make_encoder_decoder_display_tab(self, parentWidget):
        currentWidget = parentWidget
        vbox_layout = QVBoxLayout(currentWidget)

        encoderTabWidget = QTabWidget(currentWidget)
        decoderTabWidget = QTabWidget(currentWidget)

        # TODO: finish making this dynamically expandable
        self.encoderTextEdit, self.encoderHexEdit = self.make_text_hex_tab(encoderTabWidget)
        self.decoderTextEdit, self.decoderHexEdit = self.make_text_hex_tab(decoderTabWidget)

        vbox_layout.addWidget(encoderTabWidget)
        vbox_layout.addWidget(decoderTabWidget)

        encoderTabWidget.currentChanged.connect(self.encoder_tab_change)
        decoderTabWidget.currentChanged.connect(self.decoder_tab_change)

        self.encoder_tabs.append(encoderTabWidget)
        self.decoder_tabs.append(decoderTabWidget)

    def make_text_hex_tab(self, currentWidget):

        thisTabWidget = currentWidget

        textTab = QWidget(thisTabWidget)
        thisTabWidget.addTab(textTab, 'Text')
        hexTab = QWidget(thisTabWidget)
        thisTabWidget.addTab(hexTab, 'Hex')

        vlayout_text = QVBoxLayout(textTab)
        thisTextEdit = QTextEdit(textTab)
        vlayout_text.addWidget(thisTextEdit)

        vlayout_hex = QVBoxLayout(hexTab)
        thisHexEdit = Qsci.QsciScintilla(hexTab)
        ScintillaHelpers.SetScintillaProperties(self.framework, thisHexEdit, 'monospace')

        vlayout_hex.addWidget(thisHexEdit)

        return (thisTextEdit, thisHexEdit)

    def encode_data(self):
        """ Encode the specified value """
        tabInstance = self.encoder_tabs[self.mainWindow.encoderTabWidget.currentIndex()]
        if 0 == tabInstance.currentIndex():
            # read from text
            encode_value = self.encoderTextEdit.toPlainText()
        elif 1 == tabInstance.currentIndex():
            # read from hex
            encode_value = self.hexDump.undump(self.encoderHexEdit.text())
        encode_method = self.mainWindow.encodingMethodCombo.currentText()
        value = encoderlib.encode_values(encode_value, encode_method)
        self.decoderTextEdit.setPlainText(value)
        self.decoderHexEdit.setText(self.hexDump.dump(value.encode('utf-8')))
        
    def encode_wrap(self):
        """ Wrap the specified values in the encode window """
        
        encode_value = str(self.encoderTextEdit.toPlainText())
        wrap_value = self.mainWindow.encodingWrapCombo.currentText()
        value = encoderlib.wrap_encode(encode_value, wrap_value)
        self.encoderTextEdit.setPlainText(value)

    def encode_clear_data(self):
        self.encoderTextEdit.setPlainText('')
        self.encoderHexEdit.setText('')
        
    def decode_data(self):
        """ Decode the specified value from the decoder interface """
        decode_value = str(self.decoderTextEdit.toPlainText())
        decode_method = self.mainWindow.decodeMethodCombo.currentText()
        value = encoderlib.decode_values(decode_value, decode_method)
        if isinstance(value, bytes):
            self.encoderTextEdit.setPlainText(value.decode('utf-8', 'replace'))
            self.encoderHexEdit.setText(self.hexDump.dump(value))
        else:
            self.encoderTextEdit.setPlainText(value)
            self.encoderHexEdit.setText(self.hexDump.dump(value.encode('utf-8')))

    def decode_wrap(self):
        """ Wrap the specified values in the decode window """
        decode_value = str(self.decoderTextEdit.toPlainText())
        wrap_value = self.mainWindow.decodeWrapCombo.currentText()
        value = encoderlib.wrap_decode(decode_value, wrap_value)
        self.decoderTextEdit.setPlainText(value)

    def decode_clear_data(self):
        self.decoderTextEdit.setPlainText('')
        self.decoderHexEdit.setText('')

    def encoder_tab_change(self, index):
        self.handle_text_hex_tab_switch(index, self.encoderTextEdit, self.encoderHexEdit)

    def decoder_tab_change(self, index):
        self.handle_text_hex_tab_switch(index, self.decoderTextEdit, self.decoderHexEdit)

    def handle_text_hex_tab_switch(self, index, textEdit, hexEdit):
        # TODO: make this dynamic instead of depending on hard-coded values
        currentIndex = self.mainWindow.encoderTabWidget.currentIndex()
        if 0 == currentIndex:
            if 0 == index:
                # Going to Text
                value = hexEdit.text()
                if value:
                    data = self.hexDump.undump(value)
                    textEdit.setPlainText((data.decode('utf-8', 'replace')))
            elif 1 == index:
                value = textEdit.toPlainText()
                if value:
                    hexEdit.setText(self.hexDump.dump(value.encode('utf-8')))