def set_advisory_tab_pane(self, scanner_issue): advisory_pane = JEditorPane() advisory_pane.setEditable(False) advisory_pane.setEnabled(True) advisory_pane.setContentType("text/html") link_listener = LinkListener() advisory_pane.addHyperlinkListener(link_listener) advisory = "<html><b>Location</b>: {}<br><br>{}</html>" advisory_pane.setText( advisory.format(scanner_issue.getUrl().encode("utf-8"), scanner_issue.getIssueDetail())) return JScrollPane(advisory_pane)
def set_advisory_tab_pane(self, scanner_issue): advisory_pane = JEditorPane() advisory_pane.setEditable(False) advisory_pane.setEnabled(True) advisory_pane.setContentType("text/html") link_listener = LinkListener() advisory_pane.addHyperlinkListener(link_listener) fmt = "<html><b>Location</b>: {}<br><br>{}</html>" advisory_pane.setText(fmt.format(scanner_issue.getUrl(), scanner_issue.getIssueDetail())) # Set a context menu self.set_context_menu(advisory_pane, scanner_issue) return JScrollPane(advisory_pane)
class HelpPanel(JPanel): def __init__(self): JPanel.__init__(self,BorderLayout()) self.editor=JEditorPane() self.editor.setEditable(0) #self.editor.setContentType('text/html') self.editor.setContentType('text/html') sp=JScrollPane(self.editor, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED) self.add(sp,'Center') #html="<html><h1>Test</h1></html>" #self.editor.setText(html) #self.lines='HELP' self.editor.setText(HELP_TEXT) def append(self,line): self.lines="%s\n%s"%(self.lines,line) self.editor.setText(self.lines)
class DebugPanel(JPanel): def __init__(self): JPanel.__init__(self,BorderLayout()) self.editor=JEditorPane() self.editor.setEditable(0) #self.editor.setContentType('text/html') self.editor.setContentType('text/plain') sp=JScrollPane(self.editor, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED) self.add(sp,'Center') #html="<html><h1>Test</h1></html>" #self.editor.setText(html) self.lines='DEBUG OUTPUT:' self.editor.setText(self.lines) def append(self,line): try: self.lines="%s\n%s"%(self.lines,line) self.editor.setText(self.lines) except Exception,e: print e
class BurpExtender(IBurpExtender, ITab, IHttpListener, IMessageEditorController, AbstractTableModel, IContextMenuFactory, IHttpRequestResponseWithMarkers, ITextEditor): def registerExtenderCallbacks(self, callbacks): self._callbacks = callbacks #Initialize callbacks to be used later self._helpers = callbacks.getHelpers() callbacks.setExtensionName("Trishul") self._log = ArrayList() #_log used to store our outputs for a URL, which is retrieved later by the tool self._lock = Lock() #Lock is used for locking threads while updating logs in order such that no multiple updates happen at once self.intercept = 0 self.FOUND = "Found" self.CHECK = "Possible! Check Manually" self.NOT_FOUND = "Not Found" #Static Values for output #Initialize GUI self.issuesTab() self.advisoryReqResp() self.configTab() self.tabsInit() self.definecallbacks() print("Thank You for Installing Trishul") return # #Initialize Issues Tab displaying the JTree # def issuesTab(self): self.root = DefaultMutableTreeNode('Issues') frame = JFrame("Issues Tree") self.tree = JTree(self.root) self.rowSelected = '' self.tree.addMouseListener(mouseclick(self)) self.issuepanel = JScrollPane() self.issuepanel.setPreferredSize(Dimension(300,450)) self.issuepanel.getViewport().setView((self.tree)) frame.add(self.issuepanel,BorderLayout.CENTER) # #Adding Issues to Issues TreePath # def addIssues(self, branch, branchData=None): if branchData == None: branch.add(DefaultMutableTreeNode('No valid data')) else: for item in branchData: branch.add(DefaultMutableTreeNode(item)) # #Initialize the Config Tab to modify tool settings # def configTab(self): Config = JLabel("Config") self.startButton = JToggleButton("Intercept Off", actionPerformed=self.startOrStop) self.startButton.setBounds(40, 30, 200, 30) self.autoScroll = JCheckBox("Auto Scroll") self.autoScroll.setBounds(40, 80, 200, 30) self.xsscheck = JCheckBox("Detect XSS") self.xsscheck.setSelected(True) self.xsscheck.setBounds(40, 110, 200, 30) self.sqlicheck = JCheckBox("Detect SQLi") self.sqlicheck.setSelected(True) self.sqlicheck.setBounds(40, 140, 200, 30) self.ssticheck = JCheckBox("Detect SSTI") self.ssticheck.setSelected(True) self.ssticheck.setBounds(40, 170, 200, 30) self.blindxss = JCheckBox("Blind XSS") self.blindxss.setBounds(40, 200, 200, 30) self.BlindXSSText = JTextArea("", 5, 30) scrollbxssText = JScrollPane(self.BlindXSSText) scrollbxssText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED) scrollbxssText.setBounds(40, 250, 400, 110) self.configtab = JPanel() self.configtab.setLayout(None) self.configtab.setBounds(0, 0, 300, 300) self.configtab.add(Config) self.configtab.add(self.startButton) self.configtab.add(self.autoScroll) self.configtab.add(self.xsscheck) self.configtab.add(self.sqlicheck) self.configtab.add(self.ssticheck) self.configtab.add(self.blindxss) self.configtab.add(scrollbxssText) # #Turn Intercept from Proxy on or off # def startOrStop(self, event): if self.startButton.getText() == "Intercept Off": self.startButton.setText("Intercept On") self.startButton.setSelected(True) self.intercept = 1 else: self.startButton.setText("Intercept Off") self.startButton.setSelected(False) self.intercept = 0 # #Intialize the Advisory, Request and Response Tabs # def advisoryReqResp(self): self.textfield = JEditorPane("text/html", "") self.kit = HTMLEditorKit() self.textfield.setEditorKit(self.kit) self.doc = self.textfield.getDocument() self.textfield.setEditable(0) self.advisorypanel = JScrollPane() self.advisorypanel.getVerticalScrollBar() self.advisorypanel.setPreferredSize(Dimension(300,450)) self.advisorypanel.getViewport().setView((self.textfield)) self.selectedreq = [] self._requestViewer = self._callbacks.createMessageEditor(self, False) self._responseViewer = self._callbacks.createMessageEditor(self, False) self._texteditor = self._callbacks.createTextEditor() self._texteditor.setEditable(False) # #Initialize Trishul Tabs # def tabsInit(self): self.logTable = Table(self) tableWidth = self.logTable.getPreferredSize().width self.logTable.getColumn("#").setPreferredWidth(Math.round(tableWidth / 50 * 0.1)) self.logTable.getColumn("Method").setPreferredWidth(Math.round(tableWidth / 50 * 3)) self.logTable.getColumn("URL").setPreferredWidth(Math.round(tableWidth / 50 * 40)) self.logTable.getColumn("Parameters").setPreferredWidth(Math.round(tableWidth / 50 * 1)) self.logTable.getColumn("XSS").setPreferredWidth(Math.round(tableWidth / 50 * 4)) self.logTable.getColumn("SQLi").setPreferredWidth(Math.round(tableWidth / 50 * 4)) self.logTable.getColumn("SSTI").setPreferredWidth(Math.round(tableWidth / 50 * 4)) self.logTable.getColumn("Request Time").setPreferredWidth(Math.round(tableWidth / 50 * 4)) self.tableSorter = TableRowSorter(self) self.logTable.setRowSorter(self.tableSorter) self._bottomsplit = JSplitPane(JSplitPane.HORIZONTAL_SPLIT) self._bottomsplit.setDividerLocation(500) self.issuetab = JTabbedPane() self.issuetab.addTab("Config",self.configtab) self.issuetab.addTab("Issues",self.issuepanel) self._bottomsplit.setLeftComponent(self.issuetab) self.tabs = JTabbedPane() self.tabs.addTab("Advisory",self.advisorypanel) self.tabs.addTab("Request", self._requestViewer.getComponent()) self.tabs.addTab("Response", self._responseViewer.getComponent()) self.tabs.addTab("Highlighted Response", self._texteditor.getComponent()) self._bottomsplit.setRightComponent(self.tabs) self._splitpane = JSplitPane(JSplitPane.VERTICAL_SPLIT) self._splitpane.setDividerLocation(450) self._splitpane.setResizeWeight(1) self.scrollPane = JScrollPane(self.logTable) self._splitpane.setLeftComponent(self.scrollPane) self.scrollPane.getVerticalScrollBar().addAdjustmentListener(autoScrollListener(self)) self._splitpane.setRightComponent(self._bottomsplit) # #Initialize burp callbacks # def definecallbacks(self): self._callbacks.registerHttpListener(self) self._callbacks.customizeUiComponent(self._splitpane) self._callbacks.customizeUiComponent(self.logTable) self._callbacks.customizeUiComponent(self.scrollPane) self._callbacks.customizeUiComponent(self._bottomsplit) self._callbacks.registerContextMenuFactory(self) self._callbacks.addSuiteTab(self) # #Menu Item to send Request to Trishul # def createMenuItems(self, invocation): responses = invocation.getSelectedMessages() if responses > 0: ret = LinkedList() requestMenuItem = JMenuItem("Send request to Trishul") for response in responses: requestMenuItem.addActionListener(handleMenuItems(self,response, "request")) ret.add(requestMenuItem) return ret return None # #Highlighting Response # def markHttpMessage( self, requestResponse, responseMarkString ): responseMarkers = None if responseMarkString: response = requestResponse.getResponse() responseMarkBytes = self._helpers.stringToBytes( responseMarkString ) start = self._helpers.indexOf( response, responseMarkBytes, False, 0, len( response ) ) if -1 < start: responseMarkers = [ array( 'i',[ start, start + len( responseMarkBytes ) ] ) ] requestHighlights = [array( 'i',[ 0, 5 ] )] return self._callbacks.applyMarkers( requestResponse, requestHighlights, responseMarkers ) def getTabCaption(self): return "Trishul" def getUiComponent(self): return self._splitpane # #Table Model to display URL's and results based on the log size # def getRowCount(self): try: return self._log.size() except: return 0 def getColumnCount(self): return 8 def getColumnName(self, columnIndex): data = ['#','Method', 'URL', 'Parameters', 'XSS', 'SQLi', "SSTI", "Request Time"] try: return data[columnIndex] except IndexError: return "" def getColumnClass(self, columnIndex): data = [Integer, String, String, Integer, String, String, String, String] try: return data[columnIndex] except IndexError: return "" #Get Data stored in log and display in the respective columns def getValueAt(self, rowIndex, columnIndex): logEntry = self._log.get(rowIndex) if columnIndex == 0: return rowIndex+1 if columnIndex == 1: return logEntry._method if columnIndex == 2: return logEntry._url.toString() if columnIndex == 3: return len(logEntry._parameter) if columnIndex == 4: return logEntry._XSSStatus if columnIndex == 5: return logEntry._SQLiStatus if columnIndex == 6: return logEntry._SSTIStatus if columnIndex == 7: return logEntry._req_time return "" def getHttpService(self): return self._currentlyDisplayedItem.getHttpService() def getRequest(self): return self._currentlyDisplayedItem.getRequest() def getResponse(self): return self._currentlyDisplayedItem.getResponse() #For Intercepted requests perform tests in scope def processHttpMessage(self, toolFlag, messageIsRequest, messageInf): if self.intercept == 1: if toolFlag == self._callbacks.TOOL_PROXY: if not messageIsRequest: requestInfo = self._helpers.analyzeRequest(messageInf) requeststr = requestInfo.getUrl() parameters = requestInfo.getParameters() param_new = [p for p in parameters if p.getType() != 2] if len(param_new) != 0: if self._callbacks.isInScope(URL(str(requeststr))): start_new_thread(self.sendRequestToTrishul,(messageInf,)) return # #Main processing of Trishul # def sendRequestToTrishul(self,messageInfo): request = messageInfo.getRequest() req_time = datetime.datetime.today() requestURL = self._helpers.analyzeRequest(messageInfo).getUrl() messageInfo = self._callbacks.makeHttpRequest(self._helpers.buildHttpService(str(requestURL.getHost()), int(requestURL.getPort()), requestURL.getProtocol() == "https"), request) resp_time = datetime.datetime.today() time_taken = (resp_time - req_time).total_seconds() response = messageInfo.getResponse() #initialozations of default value SQLiimp = self.NOT_FOUND SSTIimp = self.NOT_FOUND XSSimp = self.NOT_FOUND Comp_req = messageInfo requestInfo = self._helpers.analyzeRequest(messageInfo) self.content_resp = self._helpers.analyzeResponse(response) requestURL = requestInfo.getUrl() parameters = requestInfo.getParameters() requeststring = self._helpers.bytesToString(request) headers = requestInfo.getHeaders() #Used to obtain GET, POST and JSON parameters from burp api param_new = [p for p in parameters if p.getType() == 0 or p.getType() == 1 or p.getType() == 6] i = 0 xssflag=0 sqliflag=0 sstiflag=0 resultxss = [] resultsqli = [] resultssti = [] xssreqresp = [] sqlireqresp = [] sstireqresp = [] ssti_description = [] sqli_description = [] xss_description = [] for i in range(len(param_new)): name = param_new[i].getName() ptype = param_new[i].getType() param_value = param_new[i].getValue() #check XSS if ticked if self.xsscheck.isSelected(): score = 0 flag1 = 0 XSSimp = self.NOT_FOUND payload_array = ["<", ">", "\\\\'asd", "\\\\\"asd", "\\", "'\""] json_payload_array = ["<", ">", "\\\\'asd", "\\\"asd", "\\", "\'\\\""] payload_all = "" json_payload = "" rand_str = "testtest" for payload in payload_array: payload_all = payload_all+rand_str+payload payload_all = URLEncoder.encode(payload_all, "UTF-8") for payload in json_payload_array: json_payload = json_payload+rand_str+payload json_payload = URLEncoder.encode(json_payload, "UTF-8") if ptype == 0 or ptype == 1: new_paramters_value = self._helpers.buildParameter(name, payload_all, ptype) updated_request = self._helpers.updateParameter(request, new_paramters_value) else: jsonreq = re.search(r"\s([{\[].*?[}\]])$", requeststring).group(1) new = jsonreq.split(name+"\":",1)[1] if new.startswith('\"'): newjsonreq = jsonreq.replace(name+"\":\""+param_value,name+"\":\""+json_payload) else: newjsonreq = jsonreq.replace(name+"\":"+param_value,name+"\":\""+json_payload+"\"") updated_request = self._helpers.buildHttpMessage(headers, newjsonreq) attack = self.makeRequest(Comp_req, updated_request) response = attack.getResponse() response_str = self._helpers.bytesToString(response) xssreqresp.append(attack) if_found_payload = "" non_encoded_symbols = "" for check_payload in payload_array: if_found_payload = rand_str+check_payload if if_found_payload in response_str: non_encoded_symbols = non_encoded_symbols+"<br>"+check_payload.replace('<', '<') score = score+1 flag1 = 1 if score > 2: XSSimp = self.CHECK if score > 3: XSSimp = self.FOUND xssflag = self.checkBetterScore(score,xssflag) if non_encoded_symbols == " \\\\'asd": XSSimp = self.NOT_FOUND if non_encoded_symbols != '': xss_description.append("The Payload <b>" + payload_all.replace('<', '<') + "</b> was passed in the request for the paramater <b>" + self._helpers.urlDecode(name) + "</b>. Some Tags were observed in the output unfiltered. A payload can be generated with the observed tags.<br>Symbols not encoded for parameter <b>" + name + "</b>: " + non_encoded_symbols) else: xss_description.append("") else: XSSimp = "Disabled" resultxss.append(XSSimp) if self.sqlicheck.isSelected(): SQLiimp = self.NOT_FOUND score = 0 value = "%27and%28select%2afrom%28select%28sleep%285%29%29%29a%29--" orig_time = datetime.datetime.today() if ptype == 0 or ptype == 1: new_paramters_value = self._helpers.buildParameter(name, value, ptype) updated_request = self._helpers.updateParameter(request, new_paramters_value) else: jsonreq = re.search(r"\s([{\[].*?[}\]])$", requeststring).group(1) new = jsonreq.split(name+"\":",1)[1] if new.startswith('\"'): newjsonreq = jsonreq.replace(name+"\":\""+param_value,name+"\":\""+value) else: newjsonreq = jsonreq.replace(name+"\":"+param_value,name+"\":\""+value+"\"") updated_request = self._helpers.buildHttpMessage(headers, newjsonreq) attack1 = self.makeRequest(Comp_req, updated_request) response1 = attack1.getResponse() new_time = datetime.datetime.today() response_str1 = self._helpers.bytesToString(response1) sqlireqresp.append(attack1) diff = (new_time - orig_time).total_seconds() if (diff - time_taken) > 3: score = 4 self.error_array = ["check the manual that corresponds to your", "You have an error", "syntax error", "SQL syntax", "SQL statement", "ERROR:", "Error:", "MySQL","Warning:","mysql_fetch_array()"] found_text = "" for error in self.error_array: if error in response_str1: found_text = found_text + error score = score + 1 if score > 1: SQLiimp = self.CHECK if score > 2: SQLiimp = self.FOUND sqliflag = self.checkBetterScore(score,sqliflag) if found_text != '': sqli_description.append("The payload <b>"+self._helpers.urlDecode(value)+"</b> was passed in the request for parameter <b>"+self._helpers.urlDecode(name)+"</b>. Some errors were generated in the response which confirms that there is an Error based SQLi. Please check the request and response for this parameter") elif (diff - time_taken) > 3: sqli_description.append("The payload <b>"+self._helpers.urlDecode(value)+"</b> was passed in the request for parameter <b>"+self._helpers.urlDecode(name)+"</b>. The response was in a delay of <b>"+str(diff)+"</b> seconds as compared to original <b>"+str(time_taken)+"</b> seconds. This indicates that there is a time based SQLi. Please check the request and response for this parameter") else: sqli_description.append("") else: SQLiimp = "Disabled" resultsqli.append(SQLiimp) if self.ssticheck.isSelected(): score = 0 SSTIimp = self.NOT_FOUND payload_array = ["${123*456}", "<%=123*567%>", "{{123*678}}"] json_payload_array = ["$\{123*456\}", "<%=123*567%>", "\{\{123*678\}\}"] payload_all = "" rand_str = "jjjjjjj" json_payload = "" for payload in payload_array: payload_all = payload_all+rand_str+payload for payload in json_payload_array: json_payload = json_payload+rand_str+payload payload_all = URLEncoder.encode(payload_all, "UTF-8") json_payload = URLEncoder.encode(json_payload, "UTF-8") if ptype == 0 or ptype == 1: new_paramters_value = self._helpers.buildParameter(name, payload_all, ptype) updated_request = self._helpers.updateParameter(request, new_paramters_value) else: jsonreq = re.search(r"\s([{\[].*?[}\]])$", requeststring).group(1) new = jsonreq.split(name+"\":",1)[1] if new.startswith('\"'): newjsonreq = jsonreq.replace(name+"\":\""+param_value,name+"\":\""+json_payload) else: newjsonreq = jsonreq.replace(name+"\":"+param_value,name+"\":\""+json_payload+"\"") updated_request = self._helpers.buildHttpMessage(headers, newjsonreq) attack = self.makeRequest(Comp_req, updated_request) response = attack.getResponse() response_str = self._helpers.bytesToString(response) self.expected_output = ["56088","69741","83394","3885","777777777777777"] for output in self.expected_output: if_found_payload = rand_str+output if if_found_payload in response_str: if output == self.expected_output[0]: sstireqresp.append(attack) ssti_description.append("Parameter <b>" + self._helpers.urlDecode(name) + "</b> is using <b>Java</b> Template<br>The value <b>" + payload_new + "</b> was passed which gave result as <b>56088</b>") score = 2 if output == self.expected_output[1]: sstireqresp.append(attack) ssti_description.append("Parameter <b>" + self._helpers.urlDecode(name) + "</b> is using <b>Ruby</b> Template<br>The value <b>" + payload_new + "</b> was passed which gave result as <b>69741</b>") score = 2 if output == self.expected_output[2]: payload_new = "{{5*'777'}}" json_payload_ssti = "\{\{5*'777'\}\}" payload = URLEncoder.encode("{{5*'777'}}", "UTF-8") json_ssti = URLEncoder.encode("\{\{5*'777'\}\}", "UTF-8") if ptype == 0 or ptype == 1: new_paramters = self._helpers.buildParameter(name, payload, ptype) ssti_updated_request = self._helpers.updateParameter(request, new_paramters) else: jsonreq = re.search(r"\s([{\[].*?[}\]])$", requeststring).group(1) new = jsonreq.split(name+"\":",1)[1] if new.startswith('\"'): newjsonreq = jsonreq.replace(name+"\":\""+param_value,name+"\":\""+json_ssti) else: newjsonreq = jsonreq.replace(name+"\":"+param_value,name+"\":\""+json_ssti+"\"") ssti_updated_request = self._helpers.buildHttpMessage(headers, newjsonreq) self.ssti_attack = self.makeRequest(Comp_req, ssti_updated_request) ssti_response = self.ssti_attack.getResponse() ssti_response_str = self._helpers.bytesToString(ssti_response) if self.expected_output[3] in ssti_response_str: sstireqresp.append(self.ssti_attack) ssti_description.append("Parameter <b>" + self._helpers.urlDecode(name) + "</b> is using <b>Twig</b> Template<br>The value <b>" + payload_new + "</b> was passed which gave result as <b>3885</b>") score = 2 elif self.expected_output[4] in ssti_response_str: sstireqresp.append(self.ssti_attack) self.responseMarkString = "777777777777777" ssti_description.append("Parameter <b>" + self._helpers.urlDecode(name) + "</b> is using <b>Jinja2</b> Template<br>The value <b>" + payload_new + "</b> was passed which gave result as <b>777777777777777</b>") score = 2 if score > 0: SSTIimp = self.CHECK if score > 1: SSTIimp = self.FOUND sstiflag = self.checkBetterScore(score,sstiflag) else: SSTIimp = "Disabled" resultssti.append(SSTIimp) if self.blindxss.isSelected(): blindxss_value = self.BlindXSSText.getText() if ptype == 0 or ptype == 1: new_paramters_value = self._helpers.buildParameter(name, blindxss_value, ptype) updated_request = self._helpers.updateParameter(request, new_paramters_value) else: jsonreq = re.search(r"\s([{\[].*?[}\]])$", requeststring).group(1) new = jsonreq.split(name+"\":",1)[1] if new.startswith('\"'): newjsonreq = jsonreq.replace(name+"\":\""+param_value,name+"\":\""+blindxss_value) else: newjsonreq = jsonreq.replace(name+"\":"+param_value,name+"\":\""+blindxss_value+"\"") updated_request = self._helpers.buildHttpMessage(headers, newjsonreq) attack = self.makeRequest(Comp_req, updated_request) if XSSimp != "Disabled": if xssflag > 3: XSSimp = self.FOUND elif xssflag > 2: XSSimp = self.CHECK else: XSSimp = self.NOT_FOUND if SSTIimp != "Disabled": if sstiflag > 1: SSTIimp = self.FOUND elif sstiflag > 0: SSTIimp = self.CHECK else: SSTIimp = self.NOT_FOUND if SQLiimp != "Disabled": if sqliflag > 3: SQLiimp = self.FOUND elif sqliflag > 2: SQLiimp = self.CHECK else: SQLiimp = self.NOT_FOUND self.addToLog(messageInfo, XSSimp, SQLiimp, SSTIimp, param_new, resultxss, resultsqli, resultssti, xssreqresp, sqlireqresp, sstireqresp , xss_description, sqli_description, ssti_description, req_time.strftime('%H:%M:%S %m/%d/%y')) # #Function used to check if the score originally and mentioned is better # def checkBetterScore(self, score, ogscore): if score > ogscore: ogscore = score return ogscore def makeRequest(self, messageInfo, message): request = messageInfo.getRequest() requestURL = self._helpers.analyzeRequest(messageInfo).getUrl() return self._callbacks.makeHttpRequest(self._helpers.buildHttpService(str(requestURL.getHost()), int(requestURL.getPort()), requestURL.getProtocol() == "https"), message) def addToLog(self, messageInfo, XSSimp, SQLiimp, SSTIimp, parameters, resultxss, resultsqli, resultssti, xssreqresp, sqlireqresp, sstireqresp, xss_description, sqli_description, ssti_description, req_time): requestInfo = self._helpers.analyzeRequest(messageInfo) method = requestInfo.getMethod() self._lock.acquire() row = self._log.size() self._log.add(LogEntry(self._callbacks.saveBuffersToTempFiles(messageInfo), requestInfo.getUrl(),method,XSSimp,SQLiimp,SSTIimp,req_time, parameters,resultxss, resultsqli, resultssti, xssreqresp, sqlireqresp, sstireqresp, xss_description, sqli_description, ssti_description)) # same requests not include again. SwingUtilities.invokeLater(UpdateTableEDT(self,"insert",row,row)) self._lock.release()
class ConsoleView(JPanel): ''' Initializes the console view and sets its layout. ''' def __init__(self, controller): ''' Creates default empty console-looking panel. It should be separated from the rest of the GUI so that users can choose to show or hide the console. Or should it be a split panel? This panel will display log and validation/lemmatization messages. It might need its own toolbar for searching, etc. It will also accept commands in later stages of development, if need be. ''' # Give reference to controller to delegate action response self.controller = controller # Make text area occupy all available space and resize with parent # window self.setLayout(BorderLayout()) # Create console-looking area self.edit_area = JEditorPane() # Although most of the styling is done using css, we need to set these # properties to ensure the html is rendered properly in the console self.edit_area.border = BorderFactory.createEmptyBorder(6, 6, 6, 6) self.edit_area.setContentType("text/html") # Disable writing in the console - required to render hyperlinks self.edit_area.setEditable(False) # Map CSS color strings to Java Color objects self.colors = {'Gray': Color(238, 238, 238), 'Black': Color(0, 0, 0), 'Yellow': Color(255, 255, 0)} # Initial call to refresh console to set the console style properties self.refreshConsole() # Set up a hyperlink listener listener = addEventListener(self.edit_area, HyperlinkListener, 'hyperlinkUpdate', self.handleEvent) # Will need scrolling controls scrollingText = JScrollPane(self.edit_area) scrollingText.setPreferredSize(Dimension(1, 150)) # Make text area auto scroll down to last printed line caret = self.edit_area.getCaret() caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE) # Add to parent panel self.add(scrollingText, BorderLayout.CENTER) def refreshConsole(self): ''' Restyle console using CSS with user selected appearance settings. ''' fontsize = self.controller.config['console_style']['fontsize']['user'] background_color = self.controller.config[ 'console_style']['background_color']['user'] font_color = self.controller.config[ 'console_style']['font_color']['user'] bodyRule = ("body {{ font-family: Monaco; font-size: {0} pt; " "font-weight: bold; color: {1} }}").format(fontsize, font_color) # Set font properties doc = self.edit_area.getDocument() doc.getStyleSheet().addRule(bodyRule) # Set background color self.edit_area.background = self.colors[background_color] self.edit_area.repaint() def scroll(self): ''' Scroll down to bottom. ''' length = self.edit_area.getDocument().getLength() self.edit_area.setCaretPosition(length) def handleEvent(self, event): ''' A simple event handler for clicked hyperlinks. ''' if event.getEventType() is EventType.ACTIVATED: atfCont = self.controller.controller.atfAreaController error_line = int(event.getDescription()) text = atfCont.getAtfAreaText() pos = atfCont.getPositionFromLine(text, error_line) # pos gives the position of the final character on the previous # line, so add 1 char to move the caret to the start of error_line # The method is called twice to catch the edge case where the user # has the caret in the correct location prior to the click # resulting in the screen not scrolling to the error line. # This would be done with some logic around getCaretPosition(), but # this would need a caret listener to be constructed. for i in xrange(2): atfCont.setCaretPosition(pos + i) # Return focus to the editor window atfCont.edit_area.requestFocusInWindow()
def build_welcome_panel(self): ''' Construct the welcome panel here. ''' panel = JPanel(GridBagLayout()) constraints = GridBagConstraints() constraints.insets = Insets(10, 10, 10, 10) message = ('<html><body>' '<h1>Welcome to Nammu</h1>' '<h2>An editor for the ORACC project<h2>' '<p>' '<a href=\'oracc\'>Click here</a> for help with ORACC.' '</p>' '<p>Learn more about Nammu <a href=\'nammu\'>here</a>.</p>' '</body></html>') # Configure a JEditorPane to display HTML for our welcome message msg_pane = JEditorPane() msg_pane.setEditable(False) kit = HTMLEditorKit() msg_pane.setEditorKit(kit) scrollPane = JScrollPane(msg_pane) # This handles the stylesheet applied to the welcome message styleSheet = kit.getStyleSheet() styleSheet.addRule('body {color:black; font-size: 16 pt; }') styleSheet.addRule('h1 {text-align:center; }') styleSheet.addRule('h2 {text-align:center; }') # Set the JEditorPane background to match the rest of the window msg_pane.border = BorderFactory.createEmptyBorder(4, 4, 4, 4) msg_pane.background = Color(238, 238, 238) # Add the message and the css and to the JEditorPane doc = kit.createDefaultDocument() msg_pane.setDocument(doc) msg_pane.setText(message) # Set up a hyperlink listener listener = addEventListener(msg_pane, HyperlinkListener, 'hyperlinkUpdate', self.handleEvent) # Configure the placement of the JEditorPane constraints.gridx = 1 constraints.gridy = 1 constraints.fill = GridBagConstraints.BOTH constraints.anchor = GridBagConstraints.CENTER panel.add(msg_pane, constraints) # Build and place the checkbox self.checkbox = JCheckBox('Don\'t show this message again.', selected=False) constraints.gridx = 1 constraints.gridy = 2 panel.add(self.checkbox, constraints) # Build and place the close button close_button = JButton('Close', actionPerformed=self.close_action) constraints.gridx = 2 constraints.gridy = 2 panel.add(close_button, constraints) return panel