class JTabTitle(JPanel, ActionListener): def __init__(self, ui, tabName): self._ui = ui self.jStatusBtn = JButton() #self.jStatusBtn.setMargin(Insets(2,0,2,0)) self.jStatusBtn = JCheckBox() self.jStatusBtn.setToolTipText(Strings.jStatusBtn_tooltip) self.jStatusBtn.setMargin(Insets(1, 5, 1, 5)) #enlarged clickable zone self.jStatusBtn.setBackground(Color.RED) #transparent background self.add(self.jStatusBtn) self.jStatusBtn.addActionListener(self) self.jLabel = JDoubleClickTextField(self, tabName) self.add(self.jLabel) self.setOpaque(False) def actionPerformed(self, event): #Check box was clicked if self.jStatusBtn == event.getSource(): if self.jStatusBtn.isSelected(): self._ui.initVars(self) pass #do nothing for now def setTabName(self, tabName): self.jLabel.setText(tabName) def getTabName(self): return self.jLabel.getText()
class BurpExtender(IBurpExtender, IExtensionStateListener, ITab): ext_name = "CompuRacerExtension" ext_version = '1.2' loaded = True t = None def registerExtenderCallbacks(self, callbacks): Cb(callbacks) Cb.callbacks.setExtensionName(self.ext_name) try: global compuracer_communication_lock # option picker item objects (for Java compatibility) item1 = {'key': 'item1', 'name': '2'} item2 = {'key': 'item2', 'name': '3'} item3 = {'key': 'item3', 'name': '4'} item4 = {'key': 'item4', 'name': '5'} item5 = {'key': 'item5', 'name': '10'} item6 = {'key': 'item6', 'name': '15'} item7 = {'key': 'item7', 'name': '20'} item8 = {'key': 'item8', 'name': '25'} item9 = {'key': 'item9', 'name': '50'} item10 = {'key': 'item10', 'name': '100'} # main splitted pane + top pane self._main_splitpane = JSplitPane(JSplitPane.VERTICAL_SPLIT) self._outer_settings_pane = JPanel(BorderLayout()) self._settings_pane = JPanel(GridBagLayout()) c = GridBagConstraints() self.label_1 = JLabel("Number of parallel requests:") c.fill = GridBagConstraints.NONE c.gridx = 0 c.gridy = 0 c.insets = Insets(0, 5, 0, 10) c.anchor = GridBagConstraints.LINE_START self._settings_pane.add(self.label_1, c) self.input_parallel_requests = JComboBox([ Item(item1), Item(item2), Item(item3), Item(item4), Item(item5), Item(item6), Item(item7), Item(item8), Item(item9), Item(item10) ]) self.input_parallel_requests.setSelectedIndex(4) self.input_parallel_requests.setToolTipText( "Select the number of parallel requests that will be sent") self.input_parallel_requests.addActionListener( self.change_parallel_requests) c.gridx = 1 c.gridy = 0 c.insets = Insets(0, 5, 0, 10) self._settings_pane.add(self.input_parallel_requests, c) self.option_allow_redirects = JCheckBox( "Allow redirects", actionPerformed=self.check_allow_redirects) self.option_allow_redirects.setToolTipText( "Select whether redirect responses are followed") c.gridx = 2 c.gridy = 0 c.insets = Insets(0, 20, 0, 10) self._settings_pane.add(self.option_allow_redirects, c) self.option_sync_last_byte = JCheckBox( "Sync last byte", actionPerformed=self.check_sync_last_byte) self.option_sync_last_byte.setToolTipText( "Select whether last byte synchronisation is enabled") c.gridx = 2 c.gridy = 1 c.insets = Insets(0, 20, 0, 0) self._settings_pane.add(self.option_sync_last_byte, c) self.label_2 = JLabel("Send timeout in seconds:") c.gridx = 0 c.gridy = 1 c.insets = Insets(0, 5, 0, 0) self._settings_pane.add(self.label_2, c) self.input_send_timeout = JComboBox([ Item(item2), Item(item4), Item(item5), Item(item7), Item(item9), Item(item10) ]) self.input_send_timeout.setSelectedIndex(3) self.input_send_timeout.setToolTipText( "Select the wait-for-response timeout after sending the request(s)" ) self.input_send_timeout.addActionListener(self.change_send_timeout) c.gridx = 1 c.gridy = 1 c.insets = Insets(0, 5, 0, 0) self._settings_pane.add(self.input_send_timeout, c) self.button_resend_batch = JButton("Resend requests") self.button_resend_batch.setToolTipText( "Resend all requests with the current configuration") self.button_resend_batch.setEnabled(False) self.button_resend_batch.addActionListener( MenuFactory.start_request_transmitter_button) c.gridx = 3 c.gridy = 0 c.insets = Insets(0, 20, 0, 10) self._settings_pane.add(self.button_resend_batch, c) immediate_data_ui_elements[ "parallel_requests"] = self.input_parallel_requests immediate_data_ui_elements[ "allow_redirects"] = self.option_allow_redirects immediate_data_ui_elements[ "sync_last_byte"] = self.option_sync_last_byte immediate_data_ui_elements[ "send_timeout"] = self.input_send_timeout immediate_data_ui_elements[ "resend_batch"] = self.button_resend_batch c = GridBagConstraints() c.anchor = GridBagConstraints.WEST self._outer_settings_pane.add(self._settings_pane, BorderLayout.WEST) self._main_splitpane.setTopComponent(self._outer_settings_pane) self._results_splitpane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT) self._main_splitpane.setBottomComponent(self._results_splitpane) # table of log entries self.tabs_right = JTabbedPane() global _textEditors, DEFAULT_RESULTS for i in range(3): _textEditors.append(Cb.callbacks.createTextEditor()) _textEditors[-1].setText(str.encode("\n" + DEFAULT_RESULTS)) self.tabs_right.add("Summary", _textEditors[0].getComponent()) self.tabs_right.add("Full result", _textEditors[1].getComponent()) self.tabs_right.add("Config", _textEditors[2].getComponent()) self._results_splitpane.setRightComponent(self.tabs_right) # tabs with request/response viewers global _requestViewers, _requestPane _requestPane = JTabbedPane() _requestViewers.append( Cb.callbacks.createMessageEditor(None, False)) _requestPane.addTab("Request", _requestViewers[-1].getComponent()) self._results_splitpane.setLeftComponent(_requestPane) # customize our UI components Cb.callbacks.customizeUiComponent(self._settings_pane) Cb.callbacks.customizeUiComponent(self.tabs_right) Cb.callbacks.customizeUiComponent(_requestPane) # add the custom tab to Burp's UI Cb.callbacks.addSuiteTab(self) except RuntimeException as e: callbacks.printError(traceback.format_exc()) e = PyException(e) print("10") print(str(self)) print("{}\t{}\n{}\n".format(e.type, e.value, e.traceback)) Cb.callbacks.registerContextMenuFactory(MenuFactory()) callbacks.registerExtensionStateListener(self) self.start_alive_checker() Cb.callbacks.printOutput('%s v%s extension loaded\n' % (self.ext_name, self.ext_version)) def change_parallel_requests(self, event): global immediate_data try: num_parallel = MenuFactory.item_selected(event) if num_parallel != immediate_data['settings'][0]: self.update_setting(0, num_parallel, "number of parallel requests") except Exception as e: print(e) def change_send_timeout(self, event): global immediate_data try: send_timeout = MenuFactory.item_selected(event) if send_timeout != immediate_data['settings'][4]: self.update_setting(4, send_timeout, "send timeout") except Exception as e: print(e) def check_allow_redirects(self, event): global immediate_data is_selected = MenuFactory.button_selected(event) if is_selected != immediate_data['settings'][2]: self.update_setting(2, is_selected, "allow redirects") def check_sync_last_byte(self, event): global immediate_data is_selected = MenuFactory.button_selected(event) if is_selected != immediate_data['settings'][3]: self.update_setting(3, is_selected, "allow redirects") def resend_batches(self, event): global _storedRequests if _storedRequests is not None: self.sen # helper method for two methods above def update_setting(self, index, new_value, text): global immediate_data success = True print("> Updating {}..".format(text)) old_value = immediate_data['settings'][index] immediate_data['settings'][index] = new_value if MenuFactory.set_immediate_mode_settings( {'settings': immediate_data['settings']}): print("> Success!") else: print("> Failed!") immediate_data['settings'][index] = old_value success = False return success # for ITab def getTabCaption(self): return "CompuRacer" # for ITab def getUiComponent(self): return self._main_splitpane # def getHttpService(self): # global _storedRequest # return _storedRequest.getHttpService() # # def getRequest(self): # global _storedRequest # return _storedRequest.getRequest() # # def getResponse(self): # global _storedRequest # return _storedRequest.getResponse() def start_alive_checker(self): self.t = threading.Thread(name='Alive checker', target=self.alive_checker) self.t.start() def closest_match(self, number, list_of_numbers): return min(list(zip(list_of_numbers, range(len(list_of_numbers)))), key=lambda item: (abs(item[0] - number), item[1])) def alive_checker(self): global compuRacer_ip, compuRacer_port, alive_check_path, racer_alive, immediate_mode, compuracer_communication_lock unloaded = False old_alive = racer_alive parallel_req_options = [2, 3, 4, 5, 10, 15, 20, 25, 50, 100] send_time_options = [3, 5, 10, 20, 50, 100] while not unloaded: try: with compuracer_communication_lock: response = requests.get("http://{}:{}/{}".format( compuRacer_ip, compuRacer_port, alive_check_path), timeout=2) racer_alive = response and response.status_code and response.status_code == 200 success, mode, settings = MenuFactory.get_immediate_mode_settings( ) if success: immediate_data['mode'] = mode immediate_data['settings'] = settings # update UI button states immediate_data_ui_elements[ "parallel_requests"].setSelectedIndex( self.closest_match( immediate_data['settings'][0], parallel_req_options)[1]) immediate_data_ui_elements[ "allow_redirects"].setSelected( bool(immediate_data['settings'][2])) immediate_data_ui_elements[ "sync_last_byte"].setSelected( bool(immediate_data['settings'][3])) immediate_data_ui_elements[ "send_timeout"].setSelectedIndex( self.closest_match( immediate_data['settings'][4], send_time_options)[1]) except Exception as e: # it surely did not work racer_alive = False print(e) if racer_alive and not old_alive: print("> Racer is now alive!") MenuFactory.set_state_of_all_buttons(True) old_alive = True elif not racer_alive and old_alive: print("> Racer became dead!") MenuFactory.set_state_of_all_buttons(False) old_alive = False time.sleep(5) if not self.loaded: unloaded = True def extensionUnloaded(self): print("\n> Unloading..") self.loaded = False self.t.join() print("> Done.")
class BurpExtender(IBurpExtender, IHttpListener, IMessageEditorTabFactory, ITab): # # implement IBurpExtender # def registerExtenderCallbacks(self, callbacks): global EXTENSION_NAME sys.stdout = callbacks.getStdout() sys.stderr = callbacks.getStderr() # keep a reference to our callbacks object self._callbacks = callbacks # obtain an extension helpers object self._helpers = callbacks.getHelpers() # set our extension name callbacks.setExtensionName(EXTENSION_NAME) # register ourselves as a Http Listener callbacks.registerHttpListener(self) # register ourselves as a message editor tab factory callbacks.registerMessageEditorTabFactory(self) # setup the UI self.initGui() # add the custom tab to Burp's UI self._callbacks.addSuiteTab(self) return # # create the Gui # def initGui(self): #~ if DEBUG: #~ import pdb; #~ pdb.set_trace() tabPane = JTabbedPane(JTabbedPane.TOP) CreditsText = "<html># Burp Custom Deserializer<br/># Copyright (c) 2016, Marco Tinari<br/>#<br/># This program is free software: you can redistribute it and/or modify<br/># it under the terms of the GNU General Public License as published by<br/># the Free Software Foundation, either version 3 of the License, or<br/># (at your option) any later version.<br/>#<br/># This program is distributed in the hope that it will be useful,<br/># but WITHOUT ANY WARRANTY; without even the implied warranty of<br/># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br/># GNU General Public License for more details.<br/>#<br/># You should have received a copy of the GNU General Public License<br/># along with this program. If not, see <http://www.gnu.org/licenses/>.)<br/></html>" label1 = JLabel( "<html>Usage:<br>1 - Select the desired encoding functions<br>2 - Enter the name of the parameter in the input field below and press the Apply button!</html>" ) label2 = JLabel(CreditsText) panel1 = JPanel() #set layout panel1.setLayout(GridLayout(11, 1)) panel2 = JPanel() panel1.add(label1) panel2.add(label2) tabPane.addTab("Configuration", panel1) tabPane.addTab("Credits", panel2) applyButton = JButton('Apply', actionPerformed=self.reloadConf) panel1.add(applyButton, BorderLayout.SOUTH) #define GET/POST/COOKIE radio button self.GETparameterTypeRadioButton = JRadioButton('GET parameter') self.POSTparameterTypeRadioButton = JRadioButton('POST parameter') self.COOKIEparameterTypeRadioButton = JRadioButton('COOKIE parameter') self.POSTparameterTypeRadioButton.setSelected(True) group = ButtonGroup() group.add(self.GETparameterTypeRadioButton) group.add(self.POSTparameterTypeRadioButton) group.add(self.COOKIEparameterTypeRadioButton) self.base64Enabled = JCheckBox("Base64 encode") self.URLEnabled = JCheckBox("URL encode") self.ASCII2HexEnabled = JCheckBox("ASCII to Hex") self.ScannerEnabled = JCheckBox( "<html>Enable serialization in Burp Scanner<br>Usage:<br>1.Place unencoded values inside intruder request and define the placeholder positions<br>2.rightclick->Actively scan defined insertion points)</html>" ) self.IntruderEnabled = JCheckBox( "<html>Enable serialization in Burp Intruder<br>Usage:<br>1.Place unencoded values inside intruder request and define the placeholder positions<br>2.Start the attack</html>" ) self.parameterName = JTextField("Parameter name goes here...", 60) #set the tooltips self.parameterName.setToolTipText( "Fill in the parameter name and apply") self.base64Enabled.setToolTipText("Enable base64 encoding/decoding") self.ASCII2HexEnabled.setToolTipText( "Enable ASCII 2 Hex encoding/decoding") self.URLEnabled.setToolTipText("Enable URL encoding/decoding") self.IntruderEnabled.setToolTipText( "Check this if You want the extension to intercept and modify every request made by the Burp Intruder containing the selected paramter" ) self.ScannerEnabled.setToolTipText( "Check this if You want the extension to intercept and modify every request made by the Burp Scanner containing the selected paramter" ) #add checkboxes to the panel panel1.add(self.parameterName) panel1.add(self.POSTparameterTypeRadioButton) panel1.add(self.GETparameterTypeRadioButton) panel1.add(self.COOKIEparameterTypeRadioButton) panel1.add(self.base64Enabled) panel1.add(self.URLEnabled) panel1.add(self.ASCII2HexEnabled) panel1.add(self.IntruderEnabled) panel1.add(self.ScannerEnabled) #assign tabPane self.tab = tabPane def reloadConf(self, event): #~ if DEBUG: #~ import pdb; pdb.set_trace() source = event.getSource() print 'APPLY button clicked. New configuration loaded.' global MAGIC_PARAMETER global PARAMETERISPOST global PARAMETERISGET global PARAMETERISCOOKIE global BASE64ENCODINGENABLED global ASCII2HEXENCODINGENABLED global URLENCODINGENABLED global INTRUDERENABLED global SCANNERENABLED MAGIC_PARAMETER = self.parameterName.getText() print 'Base64 checkbox is: ' + str(self.base64Enabled.isSelected()) if self.base64Enabled.isSelected(): BASE64ENCODINGENABLED = True else: BASE64ENCODINGENABLED = False print 'ASCII2Hex checkbox is: ' + str( self.ASCII2HexEnabled.isSelected()) if self.ASCII2HexEnabled.isSelected(): ASCII2HEXENCODINGENABLED = True else: ASCII2HEXENCODINGENABLED = False print 'URL checkbox is: ' + str(self.URLEnabled.isSelected()) if self.URLEnabled.isSelected(): URLENCODINGENABLED = True else: URLENCODINGENABLED = False print 'New Magic parameter is: ' + str(MAGIC_PARAMETER) if self.POSTparameterTypeRadioButton.isSelected(): #BODYPARAM PARAMETERISPOST = True print "parameterispost has been set to: " + str(PARAMETERISPOST) else: PARAMETERISPOST = False print "parameterispost has been set to: " + str(PARAMETERISPOST) if self.GETparameterTypeRadioButton.isSelected(): #GETPARAM PARAMETERISGET = True print "parameterisget has been set to: " + str(PARAMETERISGET) else: PARAMETERISGET = False print "parameterisget has been set to: " + str(PARAMETERISGET) if self.COOKIEparameterTypeRadioButton.isSelected(): #COOKIEPARAM PARAMETERISCOOKIE = True print "parameteriscookie has been set to: " + str( PARAMETERISCOOKIE) else: PARAMETERISCOOKIE = False print "parameteriscookie has been set to: " + str( PARAMETERISCOOKIE) if self.ScannerEnabled.isSelected(): SCANNERENABLED = True print "Scanner Enabled" else: SCANNERENABLED = False if self.IntruderEnabled.isSelected(): INTRUDERENABLED = True print "Intruder Enabled" else: INTRUDERENABLED = False # # implement IHTTPListener # def processHttpMessage(self, toolFlag, messageIsRequest, currentRequest): global PARAMETERISPOST global PARAMETERISGET global PARAMETERISCOOKIE global URLENCODINGENABLED global BASE64ENCODINGENABLED global ASCII2HEXENCODINGENABLED global INTRUDERENABLED global SCANNERENABLED #only process requests if not messageIsRequest: return #only process messages from Intruder and Scanner, otherwise exit #if (not self._callbacks.TOOL_INTRUDER == toolFlag): if ((not ( (self._callbacks.TOOL_INTRUDER == toolFlag) and INTRUDERENABLED)) and (not ((self._callbacks.TOOL_SCANNER == toolFlag) and SCANNERENABLED))): #print "exiting- toolflag:"+str(toolFlag)+' INTRUDERENABLED='+str(INTRUDERENABLED)+' SCANNERENABLED='+str(SCANNERENABLED) return #if ((not self._callbacks.TOOL_INTRUDER == toolFlag)) and ((not self._callbacks.TOOL_SCANNER == toolFlag)):#remove the comment to always enable if DEBUG: print "IHTTPListener Enabled in: " + str(toolFlag) requestInfo = self._helpers.analyzeRequest(currentRequest) timestamp = datetime.now() if DEBUG: print "Intercepting message at: ", timestamp.isoformat() #parameters = requestInfo.getParameters() dataParameter = self._helpers.getRequestParameter( currentRequest.getRequest(), MAGIC_PARAMETER) #FIXME: add exception handling for multiple parameters with the same name and/or in a different position!!! if DEBUG: print 'dataparameter:' + str(dataParameter) if (dataParameter == None): if DEBUG: print 'Parameter does not exist' return serializedValue = dataParameter.getValue() #FIXME: substitute '[AND]' placeholder with '&' charachter - we should do something more elegant here :/ serializedValue = re.sub(r'\[AND\]', '&', serializedValue) print "unserialized parameter value: ", str(serializedValue) if BASE64ENCODINGENABLED: #if base64Encode is selected serializedValue = self._helpers.base64Encode(serializedValue) if DEBUG: print "base64 encoded parameter value: ", str(serializedValue) if URLENCODINGENABLED: #if URLEncode is selected serializedValue = self._helpers.urlEncode(serializedValue) if DEBUG: print "URL ecoded parameter value: ", str(serializedValue) if ASCII2HEXENCODINGENABLED: #if ASCII2HexEncode is selected serializedValue = convert_ascii2hex(serializedValue) if DEBUG: print "ASCII2Hex ecoded parameter value: ", str( serializedValue) print "serialized parameter value: ", serializedValue if PARAMETERISPOST: if DEBUG: print "parameter is BODY" currentRequest.setRequest( self._helpers.updateParameter( currentRequest.getRequest(), self._helpers.buildParameter(MAGIC_PARAMETER, serializedValue, IParameter.PARAM_BODY))) elif PARAMETERISGET: if DEBUG: print "parameter is in URL" currentRequest.setRequest( self._helpers.updateParameter( currentRequest.getRequest(), self._helpers.buildParameter(MAGIC_PARAMETER, serializedValue, IParameter.PARAM_URL))) elif PARAMETERISCOOKIE: if DEBUG: print "parameter is a COOKIE" currentRequest.setRequest( self._helpers.updateParameter( currentRequest.getRequest(), self._helpers.buildParameter(MAGIC_PARAMETER, serializedValue, IParameter.PARAM_COOKIE))) return # # implement ITab # def getTabCaption(self): global EXTENSION_TABCAPTION return (EXTENSION_TABCAPTION) def getUiComponent(self): #~ return self._splitpane return self.tab # # implement IMessageEditorTabFactory # def createNewInstance(self, controller, editable): # create a new instance of our custom editor tab return CustomInputTab(self, controller, editable)
class BurpExtender(IBurpExtender, IHttpListener, IMessageEditorTabFactory, ITab): # # implement IBurpExtender # def registerExtenderCallbacks(self, callbacks): global EXTENSION_NAME sys.stdout = callbacks.getStdout() sys.stderr = callbacks.getStderr() # keep a reference to our callbacks object self._callbacks = callbacks # obtain an extension helpers object self._helpers = callbacks.getHelpers() # set our extension name callbacks.setExtensionName(EXTENSION_NAME) # register ourselves as a Http Listener callbacks.registerHttpListener(self) # register ourselves as a message editor tab factory callbacks.registerMessageEditorTabFactory(self) # setup the UI self.initGui() # add the custom tab to Burp's UI self._callbacks.addSuiteTab(self) return # # create the Gui # def initGui(self): #~ if DEBUG: #~ import pdb; #~ pdb.set_trace() tabPane = JTabbedPane(JTabbedPane.TOP) CreditsText = "<html># Burp Custom Deserializer<br/># Copyright (c) 2016, Marco Tinari<br/>#<br/># This program is free software: you can redistribute it and/or modify<br/># it under the terms of the GNU General Public License as published by<br/># the Free Software Foundation, either version 3 of the License, or<br/># (at your option) any later version.<br/>#<br/># This program is distributed in the hope that it will be useful,<br/># but WITHOUT ANY WARRANTY; without even the implied warranty of<br/># MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br/># GNU General Public License for more details.<br/>#<br/># You should have received a copy of the GNU General Public License<br/># along with this program. If not, see <http://www.gnu.org/licenses/>.)<br/></html>" label1 = JLabel("<html>Usage:<br>1 - Select the desired encoding functions<br>2 - Enter the name of the parameter in the input field below and press the Apply button!</html>") label2 = JLabel(CreditsText) panel1 = JPanel() #set layout panel1.setLayout(GridLayout(11,1)) panel2 = JPanel() panel1.add(label1) panel2.add(label2) tabPane.addTab("Configuration", panel1) tabPane.addTab("Credits", panel2) applyButton = JButton('Apply',actionPerformed=self.reloadConf) panel1.add(applyButton, BorderLayout.SOUTH) #define GET/POST/COOKIE radio button self.GETparameterTypeRadioButton = JRadioButton('GET parameter') self.POSTparameterTypeRadioButton = JRadioButton('POST parameter') self.COOKIEparameterTypeRadioButton = JRadioButton('COOKIE parameter') self.POSTparameterTypeRadioButton.setSelected(True) group = ButtonGroup() group.add(self.GETparameterTypeRadioButton) group.add(self.POSTparameterTypeRadioButton) group.add(self.COOKIEparameterTypeRadioButton) self.base64Enabled = JCheckBox("Base64 encode") self.URLEnabled = JCheckBox("URL encode") self.ASCII2HexEnabled = JCheckBox("ASCII to Hex") self.ScannerEnabled = JCheckBox("<html>Enable serialization in Burp Scanner<br>Usage:<br>1.Place unencoded values inside intruder request and define the placeholder positions<br>2.rightclick->Actively scan defined insertion points)</html>") self.IntruderEnabled = JCheckBox("<html>Enable serialization in Burp Intruder<br>Usage:<br>1.Place unencoded values inside intruder request and define the placeholder positions<br>2.Start the attack</html>") self.parameterName = JTextField("Parameter name goes here...",60) #set the tooltips self.parameterName.setToolTipText("Fill in the parameter name and apply") self.base64Enabled.setToolTipText("Enable base64 encoding/decoding") self.ASCII2HexEnabled.setToolTipText("Enable ASCII 2 Hex encoding/decoding") self.URLEnabled.setToolTipText("Enable URL encoding/decoding") self.IntruderEnabled.setToolTipText("Check this if You want the extension to intercept and modify every request made by the Burp Intruder containing the selected paramter") self.ScannerEnabled.setToolTipText("Check this if You want the extension to intercept and modify every request made by the Burp Scanner containing the selected paramter") #add checkboxes to the panel panel1.add(self.parameterName) panel1.add(self.POSTparameterTypeRadioButton) panel1.add(self.GETparameterTypeRadioButton) panel1.add(self.COOKIEparameterTypeRadioButton) panel1.add(self.base64Enabled) panel1.add(self.URLEnabled) panel1.add(self.ASCII2HexEnabled) panel1.add(self.IntruderEnabled) panel1.add(self.ScannerEnabled) #assign tabPane self.tab = tabPane def reloadConf(self,event): #~ if DEBUG: #~ import pdb; pdb.set_trace() source = event.getSource() print 'APPLY button clicked. New configuration loaded.' global MAGIC_PARAMETER global PARAMETERISPOST global PARAMETERISGET global PARAMETERISCOOKIE global BASE64ENCODINGENABLED global ASCII2HEXENCODINGENABLED global URLENCODINGENABLED global INTRUDERENABLED global SCANNERENABLED MAGIC_PARAMETER=self.parameterName.getText() print 'Base64 checkbox is: '+str(self.base64Enabled.isSelected()) if self.base64Enabled.isSelected(): BASE64ENCODINGENABLED=True else: BASE64ENCODINGENABLED=False print 'ASCII2Hex checkbox is: '+str(self.ASCII2HexEnabled.isSelected()) if self.ASCII2HexEnabled.isSelected(): ASCII2HEXENCODINGENABLED=True else: ASCII2HEXENCODINGENABLED=False print 'URL checkbox is: '+str(self.URLEnabled.isSelected()) if self.URLEnabled.isSelected(): URLENCODINGENABLED=True else: URLENCODINGENABLED=False print 'New Magic parameter is: '+str(MAGIC_PARAMETER) if self.POSTparameterTypeRadioButton.isSelected(): #BODYPARAM PARAMETERISPOST=True print "parameterispost has been set to: " + str(PARAMETERISPOST) else: PARAMETERISPOST=False print "parameterispost has been set to: " + str(PARAMETERISPOST) if self.GETparameterTypeRadioButton.isSelected(): #GETPARAM PARAMETERISGET=True print "parameterisget has been set to: " + str(PARAMETERISGET) else: PARAMETERISGET=False print "parameterisget has been set to: " + str(PARAMETERISGET) if self.COOKIEparameterTypeRadioButton.isSelected(): #COOKIEPARAM PARAMETERISCOOKIE=True print "parameteriscookie has been set to: " + str(PARAMETERISCOOKIE) else: PARAMETERISCOOKIE=False print "parameteriscookie has been set to: " + str(PARAMETERISCOOKIE) if self.ScannerEnabled.isSelected(): SCANNERENABLED=True print "Scanner Enabled" else: SCANNERENABLED=False if self.IntruderEnabled.isSelected(): INTRUDERENABLED=True print "Intruder Enabled" else: INTRUDERENABLED=False # # implement IHTTPListener # def processHttpMessage(self, toolFlag, messageIsRequest, currentRequest): global PARAMETERISPOST global PARAMETERISGET global PARAMETERISCOOKIE global URLENCODINGENABLED global BASE64ENCODINGENABLED global ASCII2HEXENCODINGENABLED global INTRUDERENABLED global SCANNERENABLED #only process requests if not messageIsRequest: return #only process messages from Intruder and Scanner, otherwise exit #if (not self._callbacks.TOOL_INTRUDER == toolFlag): if ((not ((self._callbacks.TOOL_INTRUDER == toolFlag) and INTRUDERENABLED)) and (not ((self._callbacks.TOOL_SCANNER == toolFlag) and SCANNERENABLED))): #print "exiting- toolflag:"+str(toolFlag)+' INTRUDERENABLED='+str(INTRUDERENABLED)+' SCANNERENABLED='+str(SCANNERENABLED) return #if ((not self._callbacks.TOOL_INTRUDER == toolFlag)) and ((not self._callbacks.TOOL_SCANNER == toolFlag)):#remove the comment to always enable if DEBUG: print "IHTTPListener Enabled in: " + str(toolFlag) requestInfo = self._helpers.analyzeRequest(currentRequest) timestamp = datetime.now() if DEBUG: print "Intercepting message at: ", timestamp.isoformat() #parameters = requestInfo.getParameters() dataParameter = self._helpers.getRequestParameter(currentRequest.getRequest(), MAGIC_PARAMETER) #FIXME: add exception handling for multiple parameters with the same name and/or in a different position!!! if DEBUG: print 'dataparameter:'+str(dataParameter) if (dataParameter == None): if DEBUG: print 'Parameter does not exist' return serializedValue = dataParameter.getValue() #FIXME: substitute '[AND]' placeholder with '&' charachter - we should do something more elegant here :/ serializedValue = re.sub(r'\[AND\]', '&', serializedValue) print "unserialized parameter value: ", str(serializedValue) if BASE64ENCODINGENABLED: #if base64Encode is selected serializedValue = self._helpers.base64Encode(serializedValue) if DEBUG: print "base64 encoded parameter value: ", str(serializedValue) if URLENCODINGENABLED: #if URLEncode is selected serializedValue = self._helpers.urlEncode(serializedValue) if DEBUG: print "URL ecoded parameter value: ", str(serializedValue) if ASCII2HEXENCODINGENABLED: #if ASCII2HexEncode is selected serializedValue = convert_ascii2hex(serializedValue) if DEBUG: print "ASCII2Hex ecoded parameter value: ", str(serializedValue) print "serialized parameter value: ", serializedValue if PARAMETERISPOST: if DEBUG: print "parameter is BODY" currentRequest.setRequest(self._helpers.updateParameter(currentRequest.getRequest(),self._helpers.buildParameter(MAGIC_PARAMETER, serializedValue,IParameter.PARAM_BODY))) elif PARAMETERISGET: if DEBUG: print "parameter is in URL" currentRequest.setRequest(self._helpers.updateParameter(currentRequest.getRequest(),self._helpers.buildParameter(MAGIC_PARAMETER, serializedValue,IParameter.PARAM_URL))) elif PARAMETERISCOOKIE: if DEBUG: print "parameter is a COOKIE" currentRequest.setRequest(self._helpers.updateParameter(currentRequest.getRequest(),self._helpers.buildParameter(MAGIC_PARAMETER, serializedValue,IParameter.PARAM_COOKIE))) return # # implement ITab # def getTabCaption(self): global EXTENSION_TABCAPTION return(EXTENSION_TABCAPTION) def getUiComponent(self): #~ return self._splitpane return self.tab # # implement IMessageEditorTabFactory # def createNewInstance(self, controller, editable): # create a new instance of our custom editor tab return CustomInputTab(self, controller, editable)
class PreferencesFrame(JFrame, ActionListener, WindowListener, ItemListener, HyperlinkListener): """Dialog with preferences """ def __init__(self, parent, title, app): from javax.swing import JCheckBox, JRadioButton, ButtonGroup self.app = app border = BorderFactory.createEmptyBorder(5, 7, 5, 7) self.getContentPane().setBorder(border) self.getContentPane().setLayout(BorderLayout(0, 5)) self.tabbedPane = JTabbedPane() #1 Tab: general panel1 = JPanel() panel1.setBorder(BorderFactory.createEmptyBorder(7, 7, 7, 7)) panel1.setLayout(BoxLayout(panel1, BoxLayout.PAGE_AXIS)) #Checkbutton to enable/disable update check when script starts self.updateCBtn = JCheckBox(self.app.strings.getString("updateCBtn")) self.updateCBtn.setToolTipText( self.app.strings.getString("updateCBtn_tooltip")) #Download tools downloadBtn = JButton(self.app.strings.getString("updatesBtn"), ImageProvider.get("dialogs", "refresh"), actionPerformed=self.on_downloadBtn_clicked) downloadBtn.setToolTipText( self.app.strings.getString("updatesBtn_tooltip")) #Checkbuttons for enabling/disabling tools toolsPanel = JPanel(BorderLayout(0, 5)) title = self.app.strings.getString("enable_disable_tools") toolsPanel.setBorder(BorderFactory.createTitledBorder(title)) infoLbl = JLabel(self.app.strings.getString("JOSM_restart_warning")) infoLbl.setFont(infoLbl.getFont().deriveFont(Font.ITALIC)) toolsPanel.add(infoLbl, BorderLayout.PAGE_START) toolsStatusPane = JPanel(GridLayout(len(self.app.realTools), 0)) self.toolsCBtns = [] for tool in self.app.realTools: toolCBtn = JCheckBox() toolCBtn.addItemListener(self) toolLbl = JLabel(tool.title, tool.bigIcon, JLabel.LEFT) self.toolsCBtns.append(toolCBtn) toolPane = JPanel() toolPane.setLayout(BoxLayout(toolPane, BoxLayout.X_AXIS)) toolPane.add(toolCBtn) toolPane.add(toolLbl) toolsStatusPane.add(toolPane) toolsPanel.add(toolsStatusPane, BorderLayout.CENTER) #Radiobuttons for enabling/disabling layers when a new one #is added layersPanel = JPanel(GridLayout(0, 1)) title = self.app.strings.getString("errors_layers_manager") layersPanel.setBorder(BorderFactory.createTitledBorder(title)) errorLayersLbl = JLabel( self.app.strings.getString("errors_layers_info")) errorLayersLbl.setFont(errorLayersLbl.getFont().deriveFont( Font.ITALIC)) layersPanel.add(errorLayersLbl) self.layersRBtns = {} group = ButtonGroup() for mode in self.app.layersModes: layerRBtn = JRadioButton(self.app.strings.getString("%s" % mode)) group.add(layerRBtn) layersPanel.add(layerRBtn) self.layersRBtns[mode] = layerRBtn #Max number of errors text field self.maxErrorsNumberTextField = JTextField() self.maxErrorsNumberTextField.setToolTipText( self.app.strings.getString("maxErrorsNumberTextField_tooltip")) self.maxErrorsNumberTFieldDefaultBorder = self.maxErrorsNumberTextField.getBorder( ) self.maxErrorsNumberTextField.getDocument().addDocumentListener( ErrNumTextListener(self)) #layout self.updateCBtn.setAlignmentX(Component.LEFT_ALIGNMENT) panel1.add(self.updateCBtn) panel1.add(Box.createRigidArea(Dimension(0, 15))) downloadBtn.setAlignmentX(Component.LEFT_ALIGNMENT) panel1.add(downloadBtn) panel1.add(Box.createRigidArea(Dimension(0, 15))) toolsPanel.setAlignmentX(Component.LEFT_ALIGNMENT) panel1.add(toolsPanel) panel1.add(Box.createRigidArea(Dimension(0, 15))) layersPanel.setAlignmentX(Component.LEFT_ALIGNMENT) panel1.add(layersPanel) panel1.add(Box.createRigidArea(Dimension(0, 15))) maxErrP = JPanel(BorderLayout(5, 0)) maxErrP.add(JLabel(self.app.strings.getString("max_errors_number")), BorderLayout.LINE_START) maxErrP.add(self.maxErrorsNumberTextField, BorderLayout.CENTER) p = JPanel(BorderLayout()) p.add(maxErrP, BorderLayout.PAGE_START) p.setAlignmentX(Component.LEFT_ALIGNMENT) panel1.add(p) self.tabbedPane.addTab(self.app.strings.getString("tab_1_title"), None, panel1, None) #2 Tab: favourite zones panel2 = JPanel(BorderLayout(5, 15)) panel2.setBorder(BorderFactory.createEmptyBorder(7, 7, 7, 7)) #status topPanel = JPanel() topPanel.setLayout(BoxLayout(topPanel, BoxLayout.Y_AXIS)) infoPanel = HtmlPanel(self.app.strings.getString("fav_zones_info")) infoPanel.getEditorPane().addHyperlinkListener(self) infoPanel.setAlignmentX(Component.LEFT_ALIGNMENT) self.favZoneStatusCBtn = JCheckBox( self.app.strings.getString("activate_fav_area"), actionListener=self) self.favZoneStatusCBtn.setToolTipText( self.app.strings.getString("activate_fav_area_tooltip")) self.favZoneStatusCBtn.setAlignmentX(Component.LEFT_ALIGNMENT) topPanel.add(infoPanel) topPanel.add(Box.createRigidArea(Dimension(0, 10))) topPanel.add(self.favZoneStatusCBtn) #table self.zonesTable = JTable() tableSelectionModel = self.zonesTable.getSelectionModel() tableSelectionModel.addListSelectionListener(ZonesTableListener(self)) columns = [ "", self.app.strings.getString("Type"), self.app.strings.getString("Name") ] tableModel = ZonesTableModel([], columns) self.zonesTable.setModel(tableModel) self.scrollPane = JScrollPane(self.zonesTable) #map self.zonesMap = JMapViewer() self.zonesMap.setZoomContolsVisible(False) self.zonesMap.setMinimumSize(Dimension(100, 200)) #buttons self.removeBtn = JButton(self.app.strings.getString("Remove"), ImageProvider.get("dialogs", "delete"), actionPerformed=self.on_removeBtn_clicked) self.removeBtn.setToolTipText( self.app.strings.getString("remove_tooltip")) newBtn = JButton(self.app.strings.getString("New"), ImageProvider.get("dialogs", "add"), actionPerformed=self.on_newBtn_clicked) newBtn.setToolTipText(self.app.strings.getString("new_tooltip")) #layout panel2.add(topPanel, BorderLayout.PAGE_START) panel2.add(self.scrollPane, BorderLayout.LINE_START) panel2.add(self.zonesMap, BorderLayout.CENTER) self.buttonsPanel = JPanel() self.buttonsPanel.add(self.removeBtn) self.buttonsPanel.add(newBtn) panel2.add(self.buttonsPanel, BorderLayout.PAGE_END) self.tabbedPane.addTab(self.app.strings.getString("tab_2_title"), None, panel2, None) #3 Tab Tools options panel3 = JPanel() panel3.setLayout(BoxLayout(panel3, BoxLayout.Y_AXIS)) panel3.setBorder(BorderFactory.createEmptyBorder(7, 7, 7, 7)) for tool in self.app.realTools: if hasattr(tool, 'prefs'): p = JPanel(FlowLayout(FlowLayout.LEFT)) p.setBorder(BorderFactory.createTitledBorder(tool.title)) p.add(tool.prefsGui) panel3.add(p) self.tabbedPane.addTab(self.app.strings.getString("tab_3_title"), None, panel3, None) self.add(self.tabbedPane, BorderLayout.CENTER) exitPanel = JPanel() saveBtn = JButton(self.app.strings.getString("OK"), ImageProvider.get("ok"), actionPerformed=self.on_saveBtn_clicked) cancelBtn = JButton(self.app.strings.getString("cancel"), ImageProvider.get("cancel"), actionPerformed=self.on_cancelBtn_clicked) saveBtn.setToolTipText(self.app.strings.getString("save_preferences")) saveBtn.setAlignmentX(0.5) exitPanel.add(saveBtn) exitPanel.add(cancelBtn) self.add(exitPanel, BorderLayout.PAGE_END) self.addWindowListener(self) self.pack() def windowClosing(self, windowEvent): self.on_cancelBtn_clicked() def hyperlinkUpdate(self, e): if e.getEventType() == HyperlinkEvent.EventType.ACTIVATED: OpenBrowser.displayUrl(e.getURL().toString()) def itemStateChanged(self, e): """A ttol has been activated/deactivated. Check if at least one tool is on. """ if all(not button.isSelected() for button in self.toolsCBtns): JOptionPane.showMessageDialog( Main.parent, self.app.strings.getString("tools_disabled_warning"), self.app.strings.getString("tools_disabled_warning_title"), JOptionPane.WARNING_MESSAGE) source = e.getItemSelectable() source.setSelected(True) def actionPerformed(self, e=None): """Enable/disable favourite zones panel """ for container in (self.scrollPane, self.buttonsPanel): self.enableComponents(container, self.favZoneStatusCBtn.isSelected()) if self.favZoneStatusCBtn.isSelected(): self.check_removeBtn_status() def enableComponents(self, container, enable): components = container.getComponents() for component in components: component.setEnabled(enable) if isinstance(component, Container): self.enableComponents(component, enable) def on_downloadBtn_clicked(self, e): update_checker.Updater(self.app, "manual") def clean_map(self): """Remove all rectangles and polygons from the map """ self.zonesMap.removeAllMapRectangles() self.zonesMap.removeAllMapPolygons() def update_gui_from_preferences(self): """Update gui status of preferences frame from config file """ #print "\n- updating Preferences gui" onOff = {"on": True, "off": False} #1 Tab #check for update self.updateCBtn.setSelected(onOff[self.app.checkUpdate]) #tools status, enabled or not for toolIndex, tool in enumerate(self.app.realTools): if "tool.%s" % tool.name in self.app.properties.keys(): configstatus = self.app.properties.getProperty("tool.%s" % tool.name) else: configstatus = "on" # new tool self.toolsCBtns[toolIndex].setSelected(onOff[configstatus]) #layers preferences for mode, button in self.layersRBtns.iteritems(): button.setSelected(mode == self.app.layersMode) #max errors number self.maxErrorsNumberTextField.setText(str(self.app.maxErrorsNumber)) #stats panel self.app.dlg.update_favourite_zone_indicator() #2 Tab #favourite area self.update_favourite_area_gui_from_preferences() self.app.dlg.update_statsPanel_status() #3 Tab #tools preferences for tool in self.app.allTools: if hasattr(tool, 'prefs') and tool.prefsGui is not None: tool.prefsGui.update_gui(tool.prefs) def update_favourite_area_gui_from_preferences(self): #status self.favZoneStatusCBtn.setSelected(self.app.favouriteZoneStatus) #table #store zones to a temporary list, used to store changes #and save them when preferences dialog is closed self.app.tempZones = list(self.app.zones) self.zonesTable.getModel().setNumRows(0) for zone in self.app.tempZones: self.zonesTable.getModel().addRow( [zone.country, zone.icon, zone.name]) if self.app.favZone is not None: selectedRow = self.app.tempZones.index(self.app.favZone) self.zonesTable.setRowSelectionInterval(selectedRow, selectedRow) self.zonesTable.getColumnModel().getColumn(0).setMaxWidth(30) self.zonesTable.getColumnModel().getColumn(1).setMaxWidth(50) #enable or disable favourite zone buttons self.actionPerformed() ### fav area editing buttons ########################################### def on_removeBtn_clicked(self, e): rowsNum = self.zonesTable.getSelectedRows() rowsNum.reverse() for rowNum in rowsNum: del self.app.tempZones[rowNum] self.zonesTable.getModel().removeRow(rowNum) if len(self.app.tempZones) != 0: if rowNum == 0: self.zonesTable.setRowSelectionInterval(0, 0) else: self.zonesTable.setRowSelectionInterval(rowNum - 1, rowNum - 1) self.check_removeBtn_status() def check_removeBtn_status(self): if self.app.tempZones != [] and len( self.zonesTable.getSelectedRows()) != 0: self.removeBtn.setEnabled(True) else: self.removeBtn.setEnabled(False) self.clean_map() def on_newBtn_clicked(self, e): try: self.newZoneDialog except AttributeError: self.newZoneDialog = NewZoneDialog(self.app) bbox = self.app.get_frame_bounds() self.app.newZone = Zone(self.app, self.app.strings.getString("New_zone"), "rectangle", ",".join(["%0.4f" % x for x in bbox]), "") self.newZoneDialog.update_gui_from_preferences() self.newZoneDialog.show() ### Exit from preferences ############################################## def on_cancelBtn_clicked(self, event=None): if hasattr(self, "newZoneDialog") and self.newZoneDialog.isVisible(): self.newZoneDialog.close_dialog() self.dispose() def on_saveBtn_clicked(self, event): """Read preferences from gui and save them to config.properties file """ #print "\n- saving preferences to config file" onOff = {True: "on", False: "off"} #1 Tab #check for update self.app.properties.setProperty("check_for_update", onOff[self.updateCBtn.isSelected()]) #tools status for toolIndex, tool in enumerate(self.app.realTools): prop = "tool.%s" % tool.name toolCBtn = self.toolsCBtns[toolIndex] self.app.properties.setProperty(prop, onOff[toolCBtn.isSelected()]) #layers preferences for mode, button in self.layersRBtns.iteritems(): if button.isSelected(): self.app.properties.setProperty("layers_mode", mode) break #max errors number try: num = Integer.parseInt(self.maxErrorsNumberTextField.getText()) except NumberFormatException: num = "" self.app.properties.setProperty("max_errors_number", str(num)) #2 Tab #Favourite zones changes = { "new": [z for z in self.app.tempZones if not z in self.app.zones], "deleted": [z for z in self.app.zones if not z in self.app.tempZones] } #delete files of removed favourite zones for zone in changes["deleted"]: f = File( File.separator.join([ self.app.SCRIPTDIR, "configuration", "favourite_zones", "%s.txt" % zone.name ])) f.delete() #create files for new favourite zones for zone in changes["new"]: print "\nsave new zone", zone.name fileName = File.separator.join([ self.app.SCRIPTDIR, "configuration", "favourite_zones", "%s.txt" % zone.name ]) f = open(fileName, "w") zoneData = zone.geomString if zone.country != "": zoneData += "|" + zone.country f.write(zoneData.encode("utf-8")) f.close() self.app.zones = self.app.tempZones if len(self.app.zones) == 0: self.app.favZone = None self.app.properties.setProperty("favourite_area.name", "") self.favZoneStatusCBtn.setSelected(False) else: if len(self.zonesTable.getSelectedRows()) == 0: self.app.favZone = self.app.zones[0] else: self.app.favZone = self.app.zones[ self.zonesTable.getSelectedRows()[0]] self.app.properties.setProperty("favourite_area.name", self.app.favZone.name) favZoneStatus = self.favZoneStatusCBtn.isSelected() self.app.properties.setProperty("favourite_area.status", onOff[favZoneStatus]) self.app.favouriteZoneStatus = favZoneStatus #stats panel self.app.dlg.update_favourite_zone_indicator() self.app.dlg.update_statsPanel_status() #3 Tab #tools preferences for tool in self.app.allTools: if hasattr(tool, 'prefs') and tool.prefsGui is not None: for pref, value in tool.prefsGui.read_gui().iteritems(): prefKey = "tool.%s.%s" % (tool.name, pref) self.app.properties.setProperty(prefKey, value) self.app.save_config() self.dispose()
def build_ui(self): """Builds the configuration screen""" labels = JPanel(GridLayout(21, 1)) checkbox = JCheckBox("Attempt to parse files for URL patterns?", False, actionPerformed=self.set_parse) stats_box = JCheckBox("Show stats?", True, actionPerformed=self.set_show_stats) # The two year old in me is laughing heartily plug_butt = JButton("Specify plugins location", actionPerformed=self.set_plugin_loc) load_plug_butt = JButton("Select plugins", actionPerformed=self.p_build_ui) parse_butt = JButton("Parse directory", actionPerformed=self.parse) clear_butt = JButton("Clear text", actionPerformed=self.clear) spider_butt = JButton("Send to Spider", actionPerformed=self.scan) save_butt = JButton("Save config", actionPerformed=self.save) rest_butt = JButton("Restore config", actionPerformed=self.restore) source_butt = JButton("Input Source File/Directory", actionPerformed=self.get_source_input) # Build grid labels.add(source_butt) labels.add(self.curr_conf) labels.add(JLabel("String Delimiter:")) labels.add(self.delim) labels.add(JLabel("Extension Whitelist:")) labels.add(self.ext_white_list) labels.add(JLabel("URL:")) labels.add(self.url) labels.add(JLabel("Path Variables")) labels.add(self.path_vars) # Leaving these here for now. # labels.add(JLabel("Cookies:")) # labels.add(self.cookies) # labels.add(JLabel("HTTP Headers:")) # labels.add(self.headers) labels.add(checkbox) labels.add(stats_box) labels.add(plug_butt) labels.add(parse_butt) labels.add(JButton("Show all endpoints", actionPerformed=self.print_endpoints)) labels.add(clear_butt) labels.add(spider_butt) labels.add(JLabel("")) labels.add(save_butt) labels.add(rest_butt) labels.add(load_plug_butt) # Tool tips! self.delim.setToolTipText("Use to manipulate the final URL. " "See About tab for example.") self.ext_white_list.setToolTipText("Define a comma delimited list of" " file extensions to parse. Use *" " to parse all files.") self.url.setToolTipText("Enter the target URL") checkbox.setToolTipText("Parse files line by line using plugins" " to enumerate language/framework specific" " endpoints") parse_butt.setToolTipText("Attempt to enumerate application endpoints") clear_butt.setToolTipText("Clear status window and the parse results") spider_butt.setToolTipText("Process discovered endpoints") save_butt.setToolTipText("Saves the current config settings") rest_butt.setToolTipText("<html>Restores previous config settings:" "<br/>-Input Directory<br/>-String Delim" "<br/>-Ext WL<br/>-URL<br/>-Plugins") source_butt.setToolTipText("Select the application's " "source directory or file to parse") self.path_vars.setToolTipText("Supply a JSON object with values" "for dynamically enumerated query" "string variables") return labels
class PreferencesFrame(JFrame, ActionListener, WindowListener, ItemListener, HyperlinkListener): """Dialog with preferences """ def __init__(self, parent, title, app): from javax.swing import JCheckBox, JRadioButton, ButtonGroup self.app = app border = BorderFactory.createEmptyBorder(5, 7, 5, 7) self.getContentPane().setBorder(border) self.getContentPane().setLayout(BorderLayout(0, 5)) self.tabbedPane = JTabbedPane() #1 Tab: general panel1 = JPanel() panel1.setBorder(BorderFactory.createEmptyBorder(7, 7, 7, 7)) panel1.setLayout(BoxLayout(panel1, BoxLayout.PAGE_AXIS)) #Checkbutton to enable/disable update check when script starts self.updateCBtn = JCheckBox(self.app.strings.getString("updateCBtn")) self.updateCBtn.setToolTipText(self.app.strings.getString("updateCBtn_tooltip")) #Download tools downloadBtn = JButton(self.app.strings.getString("updatesBtn"), ImageProvider.get("dialogs", "refresh"), actionPerformed=self.on_downloadBtn_clicked) downloadBtn.setToolTipText(self.app.strings.getString("updatesBtn_tooltip")) #Checkbuttons for enabling/disabling tools toolsPanel = JPanel(BorderLayout(0, 5)) title = self.app.strings.getString("enable_disable_tools") toolsPanel.setBorder(BorderFactory.createTitledBorder(title)) infoLbl = JLabel(self.app.strings.getString("JOSM_restart_warning")) infoLbl.setFont(infoLbl.getFont().deriveFont(Font.ITALIC)) toolsPanel.add(infoLbl, BorderLayout.PAGE_START) toolsStatusPane = JPanel(GridLayout(len(self.app.realTools), 0)) self.toolsCBtns = [] for tool in self.app.realTools: toolCBtn = JCheckBox() toolCBtn.addItemListener(self) toolLbl = JLabel(tool.title, tool.bigIcon, JLabel.LEFT) self.toolsCBtns.append(toolCBtn) toolPane = JPanel() toolPane.setLayout(BoxLayout(toolPane, BoxLayout.X_AXIS)) toolPane.add(toolCBtn) toolPane.add(toolLbl) toolsStatusPane.add(toolPane) toolsPanel.add(toolsStatusPane, BorderLayout.CENTER) #Radiobuttons for enabling/disabling layers when a new one #is added layersPanel = JPanel(GridLayout(0, 1)) title = self.app.strings.getString("errors_layers_manager") layersPanel.setBorder(BorderFactory.createTitledBorder(title)) errorLayersLbl = JLabel(self.app.strings.getString("errors_layers_info")) errorLayersLbl.setFont(errorLayersLbl.getFont().deriveFont(Font.ITALIC)) layersPanel.add(errorLayersLbl) self.layersRBtns = {} group = ButtonGroup() for mode in self.app.layersModes: layerRBtn = JRadioButton(self.app.strings.getString("%s" % mode)) group.add(layerRBtn) layersPanel.add(layerRBtn) self.layersRBtns[mode] = layerRBtn #Max number of errors text field self.maxErrorsNumberTextField = JTextField() self.maxErrorsNumberTextField.setToolTipText(self.app.strings.getString("maxErrorsNumberTextField_tooltip")) self.maxErrorsNumberTFieldDefaultBorder = self.maxErrorsNumberTextField.getBorder() self.maxErrorsNumberTextField.getDocument().addDocumentListener(ErrNumTextListener(self)) #layout self.updateCBtn.setAlignmentX(Component.LEFT_ALIGNMENT) panel1.add(self.updateCBtn) panel1.add(Box.createRigidArea(Dimension(0, 15))) downloadBtn.setAlignmentX(Component.LEFT_ALIGNMENT) panel1.add(downloadBtn) panel1.add(Box.createRigidArea(Dimension(0, 15))) toolsPanel.setAlignmentX(Component.LEFT_ALIGNMENT) panel1.add(toolsPanel) panel1.add(Box.createRigidArea(Dimension(0, 15))) layersPanel.setAlignmentX(Component.LEFT_ALIGNMENT) panel1.add(layersPanel) panel1.add(Box.createRigidArea(Dimension(0, 15))) maxErrP = JPanel(BorderLayout(5, 0)) maxErrP.add(JLabel(self.app.strings.getString("max_errors_number")), BorderLayout.LINE_START) maxErrP.add(self.maxErrorsNumberTextField, BorderLayout.CENTER) p = JPanel(BorderLayout()) p.add(maxErrP, BorderLayout.PAGE_START) p.setAlignmentX(Component.LEFT_ALIGNMENT) panel1.add(p) self.tabbedPane.addTab(self.app.strings.getString("tab_1_title"), None, panel1, None) #2 Tab: favourite zones panel2 = JPanel(BorderLayout(5, 15)) panel2.setBorder(BorderFactory.createEmptyBorder(7, 7, 7, 7)) #status topPanel = JPanel() topPanel.setLayout(BoxLayout(topPanel, BoxLayout.Y_AXIS)) infoPanel = HtmlPanel(self.app.strings.getString("fav_zones_info")) infoPanel.getEditorPane().addHyperlinkListener(self) infoPanel.setAlignmentX(Component.LEFT_ALIGNMENT) self.favZoneStatusCBtn = JCheckBox(self.app.strings.getString("activate_fav_area"), actionListener=self) self.favZoneStatusCBtn.setToolTipText(self.app.strings.getString("activate_fav_area_tooltip")) self.favZoneStatusCBtn.setAlignmentX(Component.LEFT_ALIGNMENT) topPanel.add(infoPanel) topPanel.add(Box.createRigidArea(Dimension(0, 10))) topPanel.add(self.favZoneStatusCBtn) #table self.zonesTable = JTable() tableSelectionModel = self.zonesTable.getSelectionModel() tableSelectionModel.addListSelectionListener(ZonesTableListener(self)) columns = ["", self.app.strings.getString("Type"), self.app.strings.getString("Name")] tableModel = ZonesTableModel([], columns) self.zonesTable.setModel(tableModel) self.scrollPane = JScrollPane(self.zonesTable) #map self.zonesMap = JMapViewer() self.zonesMap.setZoomContolsVisible(False) self.zonesMap.setMinimumSize(Dimension(100, 200)) #buttons self.removeBtn = JButton(self.app.strings.getString("Remove"), ImageProvider.get("dialogs", "delete"), actionPerformed=self.on_removeBtn_clicked) self.removeBtn.setToolTipText(self.app.strings.getString("remove_tooltip")) newBtn = JButton(self.app.strings.getString("New"), ImageProvider.get("dialogs", "add"), actionPerformed=self.on_newBtn_clicked) newBtn.setToolTipText(self.app.strings.getString("new_tooltip")) #layout panel2.add(topPanel, BorderLayout.PAGE_START) panel2.add(self.scrollPane, BorderLayout.LINE_START) panel2.add(self.zonesMap, BorderLayout.CENTER) self.buttonsPanel = JPanel() self.buttonsPanel.add(self.removeBtn) self.buttonsPanel.add(newBtn) panel2.add(self.buttonsPanel, BorderLayout.PAGE_END) self.tabbedPane.addTab(self.app.strings.getString("tab_2_title"), None, panel2, None) #3 Tab Tools options panel3 = JPanel() panel3.setLayout(BoxLayout(panel3, BoxLayout.Y_AXIS)) panel3.setBorder(BorderFactory.createEmptyBorder(7, 7, 7, 7)) for tool in self.app.realTools: if hasattr(tool, 'prefs'): p = JPanel(FlowLayout(FlowLayout.LEFT)) p.setBorder(BorderFactory.createTitledBorder(tool.title)) p.add(tool.prefsGui) panel3.add(p) self.tabbedPane.addTab(self.app.strings.getString("tab_3_title"), None, panel3, None) self.add(self.tabbedPane, BorderLayout.CENTER) exitPanel = JPanel() saveBtn = JButton(self.app.strings.getString("OK"), ImageProvider.get("ok"), actionPerformed=self.on_saveBtn_clicked) cancelBtn = JButton(self.app.strings.getString("cancel"), ImageProvider.get("cancel"), actionPerformed=self.on_cancelBtn_clicked) saveBtn.setToolTipText(self.app.strings.getString("save_preferences")) saveBtn.setAlignmentX(0.5) exitPanel.add(saveBtn) exitPanel.add(cancelBtn) self.add(exitPanel, BorderLayout.PAGE_END) self.addWindowListener(self) self.pack() def windowClosing(self, windowEvent): self.on_cancelBtn_clicked() def hyperlinkUpdate(self, e): if e.getEventType() == HyperlinkEvent.EventType.ACTIVATED: OpenBrowser.displayUrl(e.getURL().toString()) def itemStateChanged(self, e): """A ttol has been activated/deactivated. Check if at least one tool is on. """ if all(not button.isSelected() for button in self.toolsCBtns): JOptionPane.showMessageDialog( Main.parent, self.app.strings.getString("tools_disabled_warning"), self.app.strings.getString("tools_disabled_warning_title"), JOptionPane.WARNING_MESSAGE) source = e.getItemSelectable() source.setSelected(True) def actionPerformed(self, e=None): """Enable/disable favourite zones panel """ for container in (self.scrollPane, self.buttonsPanel): self.enableComponents(container, self.favZoneStatusCBtn.isSelected()) if self.favZoneStatusCBtn.isSelected(): self.check_removeBtn_status() def enableComponents(self, container, enable): components = container.getComponents() for component in components: component.setEnabled(enable) if isinstance(component, Container): self.enableComponents(component, enable) def on_downloadBtn_clicked(self, e): update_checker.Updater(self.app, "manual") def clean_map(self): """Remove all rectangles and polygons from the map """ self.zonesMap.removeAllMapRectangles() self.zonesMap.removeAllMapPolygons() def update_gui_from_preferences(self): """Update gui status of preferences frame from config file """ #print "\n- updating Preferences gui" onOff = {"on": True, "off": False} #1 Tab #check for update self.updateCBtn.setSelected(onOff[self.app.checkUpdate]) #tools status, enabled or not for toolIndex, tool in enumerate(self.app.realTools): if "tool.%s" % tool.name in self.app.properties.keys(): configstatus = self.app.properties.getProperty("tool.%s" % tool.name) else: configstatus = "on" # new tool self.toolsCBtns[toolIndex].setSelected(onOff[configstatus]) #layers preferences for mode, button in self.layersRBtns.iteritems(): button.setSelected(mode == self.app.layersMode) #max errors number self.maxErrorsNumberTextField.setText(str(self.app.maxErrorsNumber)) #stats panel self.app.dlg.update_favourite_zone_indicator() #2 Tab #favourite area self.update_favourite_area_gui_from_preferences() self.app.dlg.update_statsPanel_status() #3 Tab #tools preferences for tool in self.app.allTools: if hasattr(tool, 'prefs') and tool.prefsGui is not None: tool.prefsGui.update_gui(tool.prefs) def update_favourite_area_gui_from_preferences(self): #status self.favZoneStatusCBtn.setSelected(self.app.favouriteZoneStatus) #table #store zones to a temporary list, used to store changes #and save them when preferences dialog is closed self.app.tempZones = list(self.app.zones) self.zonesTable.getModel().setNumRows(0) for zone in self.app.tempZones: self.zonesTable.getModel().addRow([zone.country, zone.icon, zone.name]) if self.app.favZone is not None: selectedRow = self.app.tempZones.index(self.app.favZone) self.zonesTable.setRowSelectionInterval(selectedRow, selectedRow) self.zonesTable.getColumnModel().getColumn(0).setMaxWidth(30) self.zonesTable.getColumnModel().getColumn(1).setMaxWidth(50) #enable or disable favourite zone buttons self.actionPerformed() ### fav area editing buttons ########################################### def on_removeBtn_clicked(self, e): rowsNum = self.zonesTable.getSelectedRows() rowsNum.reverse() for rowNum in rowsNum: del self.app.tempZones[rowNum] self.zonesTable.getModel().removeRow(rowNum) if len(self.app.tempZones) != 0: if rowNum == 0: self.zonesTable.setRowSelectionInterval(0, 0) else: self.zonesTable.setRowSelectionInterval(rowNum - 1, rowNum - 1) self.check_removeBtn_status() def check_removeBtn_status(self): if self.app.tempZones != [] and len(self.zonesTable.getSelectedRows()) != 0: self.removeBtn.setEnabled(True) else: self.removeBtn.setEnabled(False) self.clean_map() def on_newBtn_clicked(self, e): try: self.newZoneDialog except AttributeError: self.newZoneDialog = NewZoneDialog(self.app) bbox = self.app.get_frame_bounds() self.app.newZone = Zone(self.app, self.app.strings.getString("New_zone"), "rectangle", ",".join(["%0.4f" % x for x in bbox]), "") self.newZoneDialog.update_gui_from_preferences() self.newZoneDialog.show() ### Exit from preferences ############################################## def on_cancelBtn_clicked(self, event=None): if hasattr(self, "newZoneDialog") and self.newZoneDialog.isVisible(): self.newZoneDialog.close_dialog() self.dispose() def on_saveBtn_clicked(self, event): """Read preferences from gui and save them to config.properties file """ #print "\n- saving preferences to config file" onOff = {True: "on", False: "off"} #1 Tab #check for update self.app.properties.setProperty("check_for_update", onOff[self.updateCBtn.isSelected()]) #tools status for toolIndex, tool in enumerate(self.app.realTools): prop = "tool.%s" % tool.name toolCBtn = self.toolsCBtns[toolIndex] self.app.properties.setProperty(prop, onOff[toolCBtn.isSelected()]) #layers preferences for mode, button in self.layersRBtns.iteritems(): if button.isSelected(): self.app.properties.setProperty("layers_mode", mode) break #max errors number try: num = Integer.parseInt(self.maxErrorsNumberTextField.getText()) except NumberFormatException: num = "" self.app.properties.setProperty("max_errors_number", str(num)) #2 Tab #Favourite zones changes = {"new": [z for z in self.app.tempZones if not z in self.app.zones], "deleted": [z for z in self.app.zones if not z in self.app.tempZones]} #delete files of removed favourite zones for zone in changes["deleted"]: f = File(File.separator.join([self.app.SCRIPTDIR, "configuration", "favourite_zones", "%s.txt" % zone.name])) f.delete() #create files for new favourite zones for zone in changes["new"]: print "\nsave new zone", zone.name fileName = File.separator.join([self.app.SCRIPTDIR, "configuration", "favourite_zones", "%s.txt" % zone.name]) f = open(fileName, "w") zoneData = zone.geomString if zone.country != "": zoneData += "|" + zone.country f.write(zoneData.encode("utf-8")) f.close() self.app.zones = self.app.tempZones if len(self.app.zones) == 0: self.app.favZone = None self.app.properties.setProperty("favourite_area.name", "") self.favZoneStatusCBtn.setSelected(False) else: if len(self.zonesTable.getSelectedRows()) == 0: self.app.favZone = self.app.zones[0] else: self.app.favZone = self.app.zones[self.zonesTable.getSelectedRows()[0]] self.app.properties.setProperty("favourite_area.name", self.app.favZone.name) favZoneStatus = self.favZoneStatusCBtn.isSelected() self.app.properties.setProperty("favourite_area.status", onOff[favZoneStatus]) self.app.favouriteZoneStatus = favZoneStatus #stats panel self.app.dlg.update_favourite_zone_indicator() self.app.dlg.update_statsPanel_status() #3 Tab #tools preferences for tool in self.app.allTools: if hasattr(tool, 'prefs') and tool.prefsGui is not None: for pref, value in tool.prefsGui.read_gui().iteritems(): prefKey = "tool.%s.%s" % (tool.name, pref) self.app.properties.setProperty(prefKey, value) self.app.save_config() self.dispose()
def build_ui(self): """Builds the configuration screen""" labels = JPanel(GridLayout(21, 1)) checkbox = JCheckBox("Attempt to parse files for URL patterns?", False, actionPerformed=self.set_parse) stats_box = JCheckBox("Show stats?", True, actionPerformed=self.set_show_stats) # The two year old in me is laughing heartily plug_butt = JButton("Specify plugins location", actionPerformed=self.set_plugin_loc) load_plug_butt = JButton("Select plugins", actionPerformed=self.p_build_ui) parse_butt = JButton("Parse directory", actionPerformed=self.parse) clear_butt = JButton("Clear text", actionPerformed=self.clear) spider_butt = JButton("Send to Spider", actionPerformed=self.scan) save_butt = JButton("Save config", actionPerformed=self.save) rest_butt = JButton("Restore config", actionPerformed=self.restore) source_butt = JButton("Input Source File/Directory", actionPerformed=self.get_source_input) # Build grid labels.add(source_butt) labels.add(self.curr_conf) labels.add(JLabel("String Delimiter:")) labels.add(self.delim) labels.add(JLabel("Extension Whitelist:")) labels.add(self.ext_white_list) labels.add(JLabel("URL:")) labels.add(self.url) # Leaving these here for now. # labels.add(JLabel("Cookies:")) # labels.add(self.cookies) # labels.add(JLabel("HTTP Headers:")) # labels.add(self.headers) labels.add(checkbox) labels.add(stats_box) labels.add(plug_butt) labels.add(parse_butt) labels.add(JButton("Show all endpoints", actionPerformed=self.print_endpoints)) labels.add(clear_butt) labels.add(spider_butt) labels.add(JLabel("")) labels.add(save_butt) labels.add(rest_butt) labels.add(load_plug_butt) # Tool tips! self.delim.setToolTipText("Use to manipulate the final URL. " "See About tab for example.") self.ext_white_list.setToolTipText("Define a comma delimited list of" " file extensions to parse. Use *" " to parse all files.") self.url.setToolTipText("Enter the target URL") checkbox.setToolTipText("Parse files line by line using plugins" " to enumerate language/framework specific" " endpoints") parse_butt.setToolTipText("Attempt to enumerate application endpoints") clear_butt.setToolTipText("Clear status window and the parse results") spider_butt.setToolTipText("Process discovered endpoints") save_butt.setToolTipText("Saves the current config settings") rest_butt.setToolTipText("<html>Restores previous config settings:" "<br/>-Input Directory<br/>-String Delim" "<br/>-Ext WL<br/>-URL<br/>-Plugins") source_butt.setToolTipText("Select the application's " "source directory or file to parse") return labels
class WorkHelper(JFrame): def __init__(self): super(WorkHelper, self).__init__() self.clipboard = Toolkit.getDefaultToolkit().getSystemClipboard() #self.initUI() #def initUI(self): #panel = JPanel() #self.getContentPane().add(panel) ############################################################# # Layout layout = GroupLayout(self.getContentPane()) self.getContentPane().setLayout(layout) layout.setAutoCreateGaps(True) layout.setAutoCreateContainerGaps(True) ############################################################# ############################################################# # Scroll Area Input + Output Larea1 = JLabel("InputArea:") Larea2 = JLabel("OutputArea:") Sarea1 = JScrollPane() Sarea2 = JScrollPane() self.area1 = JTextArea() self.area1.setToolTipText("Input Area") self.area1.setEditable(True) self.area1.setBorder(BorderFactory.createLineBorder(Color.gray)) Sarea1.setPreferredSize(Dimension(300,100)) Sarea1.getViewport().setView((self.area1)) self.area2 = JTextArea() self.area2.setToolTipText("Output Area") self.area2.setEditable(False) self.area2.setBorder(BorderFactory.createLineBorder(Color.gray)) Sarea2.setPreferredSize(Dimension(300,100)) Sarea2.getViewport().setView((self.area2)) ############################################################# ############################################################# # Buttons self.cCurly = JCheckBox("Curly"); self.cCurly.setToolTipText("When 'Checked' Curly Brackets will surround the Categories") self.cCurly.setSelected(1) self.cCtClipB = JCheckBox("Auto-Copy"); self.cCtClipB.setToolTipText("When 'Checked' after the Categories are created they will added to the clipboard") self.cCtClipB.setSelected(1) self.cSemiC = JCheckBox("SemiColumn"); self.cSemiC.setToolTipText("When 'Checked' after the Categories are created at the end will be a semicolomn") self.cSemiC.setSelected(1) bRemoveNBSP_L = JButton("Clean LText", actionPerformed=self.bRemoveNBSP_L) bRemoveNBSP_L.setToolTipText("Removes Spaces, Tabs from the start of every text line from the input Area") bRemoveNBSP_R = JButton("Clean RText", actionPerformed=self.bRemoveNBSP_R) bRemoveNBSP_R.setToolTipText("Removes Spaces, Tabs from the end of every text line from the input Area") bCopyToInput = JButton("Copy to Input", actionPerformed=self.bCopyToInput) bCopyToInput.setToolTipText("Copy the text from the Output Area to the Input Area for further Operations") bClear = JButton("Clear", actionPerformed=self.bClear) bClear.setToolTipText("Clears the text form both Input and Output text Areas") self.iStart = JTextField(maximumSize=Dimension(40,25)) self.iStart.setToolTipText("The Start Index for the Making of the Categories") self.RThis = JTextField() self.RThis = JTextField(maximumSize=Dimension(120,25)) self.RThis.setToolTipText("Text to be replaced or The Starting C_Index") self.RThat = JTextField() self.RThat = JTextField(maximumSize=Dimension(120,25)) self.RThat.setToolTipText("Text to be placed or The Finish C_Index") bSandReplace = JButton("Replace Text", actionPerformed=self.bSandReplace) bSandReplace.setToolTipText("Replace the text from This with Thext from That in the Text from the Input Area and displays it in the Output Area") bcCat = JButton("CreatCateg", actionPerformed=self.bcCat) bcCat.setToolTipText("Create a categorical form starting C_Index to finish C_Index; Use the above text boxes to define the indexes") bC_S = JButton("Create _Series", actionPerformed=self.bC_S) bC_S.setToolTipText("Create a series form starting C_Index to finish C_Index; Use the above text boxes to define the indexes; It will create a series for every row in the Input Area") bM_Categories = JButton("Categories", actionPerformed=self.mCategories) bM_Categories.setToolTipText("Make Categories using the lines from the Input Area") #bM_Categories = JButton(maximumSize=Dimension(40,25)) # de incercat daca merge cu ; sa grupezi in [dsa] elementele ############################################################# ############################################################# # Aplication Layout 2 groups one Horizontal and one Vertical layout.setHorizontalGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup() .addComponent(Larea1) .addComponent(Sarea1) .addComponent(Sarea2) .addComponent(bCopyToInput) .addComponent(Larea2)) .addGroup(layout.createParallelGroup() .addGroup(layout.createSequentialGroup() .addComponent(bM_Categories) .addComponent(self.iStart)) .addGroup(layout.createSequentialGroup() .addComponent(self.cCurly) .addComponent(self.cSemiC) .addComponent(self.cCtClipB)) .addGroup(layout.createSequentialGroup() .addComponent(bRemoveNBSP_L) .addComponent(bRemoveNBSP_R)) .addGroup(layout.createSequentialGroup() .addComponent(self.RThis) .addComponent(self.RThat)) .addGroup(layout.createSequentialGroup() .addComponent(bSandReplace) .addComponent(bcCat)) .addGroup(layout.createSequentialGroup() .addComponent(bC_S)) .addComponent(bClear)) ) layout.setVerticalGroup(layout.createSequentialGroup() .addComponent(Larea1) .addGroup(layout.createParallelGroup() .addComponent(Sarea1) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup() .addComponent(bM_Categories) .addComponent(self.iStart)) .addGroup(layout.createParallelGroup() .addComponent(self.cCurly) .addComponent(self.cSemiC) .addComponent(self.cCtClipB)) .addGroup(layout.createParallelGroup() .addComponent(bRemoveNBSP_L) .addComponent(bRemoveNBSP_R)) .addGroup(layout.createParallelGroup() .addComponent(self.RThis) .addComponent(self.RThat)) .addGroup(layout.createParallelGroup() .addComponent(bSandReplace) .addComponent(bcCat)) .addGroup(layout.createParallelGroup() .addComponent(bC_S)) ) ) .addGroup(layout.createParallelGroup() .addComponent(bCopyToInput) .addComponent(bClear)) .addComponent(Larea2) .addGroup(layout.createParallelGroup() .addComponent(Sarea2)) ) #layout.linkSize(SwingConstants.HORIZONTAL, [ok, bCopyToInput, close, bM_Categories]) layout.linkSize(SwingConstants.HORIZONTAL, [self.RThis,self.RThat,bRemoveNBSP_L,bRemoveNBSP_R,bCopyToInput,bM_Categories,bSandReplace,bcCat,bC_S]) #layout.linkSize(SwingConstants.HORIZONTAL, [self.cCurly,bM_Categories]) ############################################################# ############################################################# # Aplication Settings self.pack() #self.setPreferredSize(Dimension(1000, 1000)) self.setTitle("Workhelper") self.setSize(800, 500) self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) self.setLocationRelativeTo(None) self.setVisible(True) ############################################################# ############################################################# # WorkHelper class methods: def onQuit(self, e): "@sig public void setExpression(java.lang.String e)" System.exit(0) # def addToClipBoard(self, text): # "@sig public void setExpression(java.lang.String text)" # command = 'echo ' + text.strip() + '| clip' # os.system(command) # brute method for pasting into clipboard on windows def mCategories(self, e): "@sig public void setExpression(java.lang.String e)" """ Takes every line of text form the Input Area and by using a string composotion it creates the output in the SPSS dimension categories format. """ try: StartIndex = int(self.iStart.getText()) except ValueError: StartIndex=1 text=self.area1.getText().rstrip() counter=StartIndex lastindex=0 textO="" for i in range(0,len(text)): if text[i]=='\n': textO=textO+("_"+str(counter)+' "'+text[lastindex:i]+'",\n') lastindex=i+1 counter=counter+1 if len(text[lastindex:len(text)])>0: textO=textO+("_"+str(counter)+' "'+text[lastindex:len(text)]+'"') if len(textO)>0: if self.cCurly.isSelected(): textO = "{\n"+ textO + "\n}" if self.cSemiC.isSelected(): textO = textO + ";" self.copyToClipboard(textO) self.area2.setText(textO) def copyToClipboard(self, text): if self.cCtClipB.isSelected(): stringSelection = StringSelection(text) self.clipboard.setContents(stringSelection, None) def bCopyToInput(self, e): "@sig public void setExpression(java.lang.String e)" """Copy the Text from the Output Area to the input Area for further operations""" self.area1.setText(self.area2.getText()) def bRemoveNBSP_L(self, e): "@sig public void setExpression(java.lang.String e)" text=self.area1.getText().rstrip() textO="" lastindex=0 for i in range(0,len(text)): if text[i] == '\n': textO = textO+text[lastindex:i].lstrip()+"\n" lastindex=i+1 #print(text[0:i].lstrip()+'\n') if len(text[lastindex:len(text)])>0: textO=textO+text[lastindex:len(text)].lstrip() self.area2.setText(textO) def bRemoveNBSP_R(self, e): "@sig public void setExpression(java.lang.String e)" text=self.area1.getText().rstrip() textO="" lastindex=0 for i in range(0,len(text)): if text[i] == '\n': textO = textO+text[lastindex:i].rstrip()+"\n" lastindex=i+1 #print(text[0:i].lstrip()+'\n') if len(text[lastindex:len(text)])>0: textO=textO+text[lastindex:len(text)].rstrip() self.area2.setText(textO) def bClear(self, e): "@sig public void setExpression(java.lang.String e)" self.area1.setText("") self.area2.setText("") def bcCat(self, e): "@sig public void setExpression(java.lang.String e)" try: StartIndex = int(self.RThis.getText()) except ValueError: StartIndex=1 try: FinishIndex = int(self.RThat.getText()) except ValueError: FinishIndex=1 cCats="" for i in range(StartIndex,FinishIndex+1): if i<>FinishIndex: cCats=cCats+"_"+str(i)+"," else: cCats=cCats+"_"+str(i) if StartIndex<FinishIndex: cCats="{"+cCats+"}" self.copyToClipboard(cCats) self.area2.setText(cCats) def bSandReplace(self, e): self.area2.setText(self.area1.getText().replace(self.RThis.getText(),self.RThat.getText())) def bC_S(self, e): "@sig public void setExpression(java.lang.String e)" try: StartIndex = int(self.RThis.getText()) except ValueError: StartIndex=1 try: FinishIndex = int(self.RThat.getText()) except ValueError: FinishIndex=1 if StartIndex<FinishIndex: text=self.area1.getText().rstrip() lastindex=0 textO="" for i in range(0,len(text)): if text[i]=='\n': counter=StartIndex for j in range(StartIndex,FinishIndex+1): textO=textO+(text[lastindex:i]+"_"+str(counter)+" ") counter=counter+1 lastindex=i+1 textO=textO+'\n' #if len(text[lastindex:len(text)])>0: # textO=textO+("_"+str(counter)+' "'+text[lastindex:len(text)]+'"') if lastindex==0 and len(text)>0: counter=StartIndex for j in range(StartIndex,FinishIndex+1): textO=textO+(text[lastindex:i]+"_"+str(counter)+" ") counter=counter+1 if len(textO)>0: self.copyToClipboard(textO) self.area2.setText(textO)
class CumulusUI(JFrame): '''Java Swing used to create a JFrame UI. On init the objects will be populated with information derived from URL requests to CUMULUS and the open CWMS watershed. ''' def __init__(self, arg_dict): super(CumulusUI, self).__init__() # Load argument from the command line self.start_time = arg_dict['start_time'] self.end_time = arg_dict['end_time'] self.dss_path = arg_dict['dss_path'] self.cwms_home = arg_dict['cwms_home'] self.config = arg_dict['config'] # Get the DSS Path if one was saved in the "cumulus.config" file if os.path.isfile(self.config): with open(os.path.join(APPDATA, "cumulus.config")) as f: self.dss_path = f.read() # Get the basins and products, load JSON, create lists for JList, and create dictionaries self.basin_download = json.loads(self.http_get(url_basins)) self.jlist_basins = ["{}:{}".format(b['office_symbol'], b['name']) for b in self.basin_download] self.basin_meta = dict(zip(self.jlist_basins, self.basin_download)) self.jlist_basins.sort() self.product_download = json.loads(self.http_get(url_products)) self.jlist_products = ["{}".format(p['name'].replace("_", " ").title()) for p in self.product_download] self.product_meta = dict(zip(self.jlist_products, self.product_download)) self.jlist_products.sort() btn_submit = JButton() lbl_start_date = JLabel() lbl_end_date = JLabel() self.txt_select_file = JTextField() btn_select_file = JButton() lbl_origin = JLabel() lbl_extent = JLabel() lbl_select_file = JLabel() self.txt_start_time = JTextField() self.txt_end_time = JTextField() jScrollPane1 = JScrollPane() self.lst_product = JList() self.lst_product = JList(self.jlist_products, valueChanged = self.choose_product) jScrollPane2 = JScrollPane() self.lst_watershed = JList() self.lst_watershed = JList(self.jlist_basins, valueChanged = self.choose_watershed) self.cwms_dssname = JCheckBox() self.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE) self.setTitle("Cumulus CAVI UI") self.setLocation(Point(10, 10)) self.setLocationByPlatform(True) self.setName("CumulusCaviUi") self.setResizable(False) btn_submit.setFont(Font("Tahoma", 0, 18)) btn_submit.setText("Submit") btn_submit.actionPerformed = self.submit lbl_start_date.setText("Start Date/Time") lbl_end_date.setText("End Date/Time") self.txt_select_file.setToolTipText("FQPN to output file (.dss)") btn_select_file.setText("...") btn_select_file.setToolTipText("Select File...") btn_select_file.actionPerformed = self.select_file lbl_origin.setText("Minimum (x,y):") lbl_extent.setText("Maximum (x,y):") lbl_select_file.setText("Output File Location") self.txt_start_time.setToolTipText("Start Time") self.txt_end_time.setToolTipText("End Time") self.lst_product.setBorder(BorderFactory.createTitledBorder(None, "Available Products", TitledBorder.CENTER, TitledBorder.TOP, Font("Tahoma", 0, 14))) self.lst_product.setFont(Font("Tahoma", 0, 14)) jScrollPane1.setViewportView(self.lst_product) self.lst_product.getAccessibleContext().setAccessibleName("Available Products") self.lst_product.getAccessibleContext().setAccessibleParent(jScrollPane2) self.lst_watershed.setBorder(BorderFactory.createTitledBorder(None, "Available Watersheds", TitledBorder.CENTER, TitledBorder.TOP, Font("Tahoma", 0, 14))) self.lst_watershed.setFont(Font("Tahoma", 0, 14)) self.lst_watershed.setSelectionMode(ListSelectionModel.SINGLE_SELECTION) jScrollPane2.setViewportView(self.lst_watershed) self.cwms_dssname.setText("CWMS DSS filename") self.cwms_dssname.setToolTipText("Parameter.yyyy.mm.dss") self.cwms_dssname.setVisible(False) layout = GroupLayout(self.getContentPane()); self.getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING, False) .addComponent(lbl_select_file) .addComponent(jScrollPane1) .addComponent(jScrollPane2) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING) .addComponent(btn_submit) .addComponent(self.txt_select_file, GroupLayout.PREFERRED_SIZE, 377, GroupLayout.PREFERRED_SIZE)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addComponent(btn_select_file)) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(lbl_start_date) .addComponent(self.txt_start_time, GroupLayout.PREFERRED_SIZE, 170, GroupLayout.PREFERRED_SIZE)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(self.txt_end_time, GroupLayout.PREFERRED_SIZE, 170, GroupLayout.PREFERRED_SIZE) .addComponent(lbl_end_date)))) .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ) layout.setVerticalGroup( layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addGap(25, 25, 25) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(lbl_start_date) .addComponent(lbl_end_date)) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(self.txt_start_time, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent(self.txt_end_time, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)) .addGap(18, 18, 18) .addComponent(jScrollPane2, GroupLayout.PREFERRED_SIZE, 201, GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) .addComponent(jScrollPane1, GroupLayout.PREFERRED_SIZE, 201, GroupLayout.PREFERRED_SIZE) .addGap(18, 18, Short.MAX_VALUE) .addComponent(lbl_select_file) .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE) .addComponent(self.txt_select_file, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent(btn_select_file)) .addGap(18, 18, 18) .addComponent(btn_submit) .addContainerGap()) ) self.txt_select_file.setText(self.dss_path) self.txt_start_time.setText(self.start_time) self.txt_end_time.setText(self.end_time) self.pack() self.setLocationRelativeTo(None) def http_get(self, url): '''Return java.lang.String JSON Input: java.lang.String URL ''' start_timer = System.currentTimeMillis() try: url = URL(url) urlconnect = url.openConnection() br = BufferedReader( InputStreamReader( urlconnect.getInputStream(), "UTF-8" ) ) s = br.readLine() br.close() except MalformedURLException() as ex: cumulus_logger.error(str(ex)) MessageBox.showError(str(ex), "Exception") raise except IOException as ex: cumulus_logger.error(str(ex)) MessageBox.showError(str(ex), "Exception") raise end_timer = System.currentTimeMillis() cumulus_logger.debug( "HTTP GET (milliseconds): {}".format( (end_timer - start_timer) ) ) return s def http_post(self, json_string, url): '''Return java.lang.String JSON Input: java.lang.String JSON, java.lang.String URL ''' start_timer = System.currentTimeMillis() try: # Get a connection and set the request properties url = URL(url) urlconnect = url.openConnection() urlconnect.setDoOutput(True) urlconnect.setRequestMethod("POST") urlconnect.setRequestProperty("Content-Type", "application/json; UTF-8") urlconnect.setRequestProperty("Accept", "application/json") # Write to the body bw = BufferedWriter( OutputStreamWriter( urlconnect.getOutputStream() ) ) bw.write(json_string) bw.flush() bw.close() # Read the result from the POST br = BufferedReader( InputStreamReader( urlconnect.getInputStream(), "UTF-8" ) ) s = br.readLine() br.close() except MalformedURLException() as ex: cumulus_logger.error(str(ex)) MessageBox.showError(str(ex), "Exception") raise Exception(ex) except IOException as ex: cumulus_logger.error(str(ex)) MessageBox.showError(str(ex), "Exception") raise Exception(ex) end_timer = System.currentTimeMillis() cumulus_logger.debug( "HTTP GET (milliseconds): {}".format( (end_timer - start_timer) ) ) return s def json_build(self): '''Return JSON string or 'None' if failed The returning JSON string is from the UI and used when POSTing to the Cumulus API. ''' conf = { 'datetime_start': None, 'datetime_end': None, 'watershed_id': None, 'product_id': None, } try: tf = TimeFormatter() tz = tf.zid st = tf.parse_zoned_date_time(self.txt_start_time.getText(), tz) et = tf.parse_zoned_date_time(self.txt_end_time.getText(), tz) conf['datetime_start'] = st.format(tf.iso_instant()) conf['datetime_end'] = et.format(tf.iso_instant()) except DateTimeParseException as ex: MessageBox.showWarning(ex, "Exception") selected_watershed = self.lst_watershed.getSelectedValue() selected_products = self.lst_product.getSelectedValues() if selected_watershed is not None: watershed_id = self.basin_meta[selected_watershed]['id'] conf['watershed_id'] = watershed_id else: MessageBox.showWarning( "No Watershed Selected", "Exception" ) return None product_ids = list() if len(selected_products) > 0: for p in selected_products: product_ids.append(self.product_meta[p]['id']) conf['product_id'] = product_ids else: MessageBox.showWarning( "No Products Selected", "Exception" ) return None return json.dumps(conf) def choose_product(self, event): '''The event here is a javax.swing.event.ListSelectionEvent because it comes from a Jlist. Use getValueIsAdjusting() to only get the mouse up value. ''' output_str = '''{name} After: {after} Before: {before} Parameter: {para} Unit: {u} ''' index = self.lst_product.selectedIndex if not event.getValueIsAdjusting(): pnames = self.lst_product.getSelectedValues() for pname in pnames: cumulus_logger.info("~" * 50) cumulus_logger.info("Product: {}".format(pname)) cumulus_logger.info( "After time: {}".format(self.product_meta[pname]['after'])) cumulus_logger.info( "Before time: {}".format(self.product_meta[pname]['before'])) cumulus_logger.info( "Parameter: {}".format(self.product_meta[pname]['parameter'])) cumulus_logger.info( "unit: {}".format(self.product_meta[pname]['unit'])) def choose_watershed(self, event): '''The event here is a javax.swing.event.ListSelectionEvent because it comes from a Jlist. Use getValueIsAdjusting() to only get the mouse up value. ''' index = self.lst_watershed.selectedIndex if not event.getValueIsAdjusting(): _dict = self.basin_meta[self.lst_watershed.getSelectedValue()] def select_file(self, event): '''Provide the user a JFileChooser to select the DSS file data is to download to. Event is a java.awt.event.ActionEvent ''' fc = FileChooser(self.txt_select_file) fc.title = "Select Output DSS File" _dir = os.path.dirname(self.dss_path) fc.set_current_dir(File(_dir)) fc.show() def submit(self, event): '''Collect user inputs and initiate download of DSS files to process. Event is a java.awt.event.ActionEvent ''' start_timer = end_timer = System.currentTimeMillis() # Build the JSON from the UI inputs and POST if we have JSON json_string = self.json_build() cumulus_logger.debug("JSON String Builder: {}".format(json_string)) if json_string is not None: cumulus_logger.info("*" * 50) cumulus_logger.info("Initiated Cumulus Product Request") cumulus_logger.info("*" * 50) post_result = self.http_post(json_string, url_downloads) json_post_result = json.loads(post_result) id = json_post_result['id'] max_timeout = 180 while max_timeout > 0: get_result = self.http_get("/".join([url_downloads, id])) if get_result is not None: json_get_result = json.loads(get_result) progress = json_get_result['progress'] #100% stat = json_get_result['status'] #SUCCESS fname = json_get_result['file'] # not null cumulus_logger.info("Status: {:>10}; Progress: {:>4.1f}%; Timeout: {:>4}".format(stat, progress, max_timeout)) if stat == 'FAILED': cumulus_logger.error("Failed to load grid products.") MessageBox.showError( "Failed to load grid products.", "Failed Download" ) break if int(progress) == 100 and stat == 'SUCCESS' and fname is not None: dest_dssfile = self.txt_select_file.getText() cumulus_logger.debug("DSS Download Filname: {}".format(fname)) downloaded_dssfile = download_dss(fname) if downloaded_dssfile is not None: cumulus_logger.info("DSS file downloaded.") merged_dssfiles = merge_dss(downloaded_dssfile, dest_dssfile) if len(merged_dssfiles) > 0: end_timer = System.currentTimeMillis() msg = "DSS file downloaded and merged to: {}".format( '\n'.join([f for f in merged_dssfiles]) ) cumulus_logger.info(msg) MessageBox.showInformation(msg, "Successful Processing" ) else: msg = "DSS file merge unsuccessful" cumulus_logger.warning(msg) MessageBox.showWarning(msg, "Unsuccessful Merge" ) else: msg = "Downloading and processing the DSS file failed!" cumulus_logger.error(msg) MessageBox.showError(msg, "Failed Processing" ) break else: Thread.sleep(2000) max_timeout -= 1 cumulus_logger. info( "Submit time duration (milliseconds): {}".format( (end_timer - start_timer) ) ) # Try to clean up any dss6 and dss7 files in the temp try: tempdir = tempfile.gettempdir() dss_temp_files = os.listdir(tempdir) for f in dss_temp_files: if (f.endswith(".dss") or f.endswith(".dss")): os.remove(os.path.join(tempdir, f)) except OSError as ex: cumulus_logger.warning(str(ex))
class WorkHelper(JFrame): def __init__(self): super(WorkHelper, self).__init__() self.clipboard = Toolkit.getDefaultToolkit().getSystemClipboard() ############################################################# # Layout: layout = GroupLayout(self.getContentPane()) self.getContentPane().setLayout(layout) layout.setAutoCreateGaps(True) layout.setAutoCreateContainerGaps(True) ############################################################# ############################################################# # Frame Area: Larea1 = JLabel("InputArea:") Sarea1 = JScrollPane() self.area1 = JTextArea() self.area1.setToolTipText("Input Area") self.area1.setEditable(True) self.area1.setBorder(BorderFactory.createLineBorder(Color.gray)) Sarea1.setPreferredSize(Dimension(300,100)) Sarea1.getViewport().setView((self.area1)) bClear = JButton("Clear", actionPerformed=self.bClear) bClear.setToolTipText("Clears the text form both Input and Output text Areas") bCopyToInput = JButton("Copy to Input", actionPerformed=self.bCopyToInput) bCopyToInput.setToolTipText("Copy the text from the Output Area to the Input Area for further Operations") self.cCtClipB = JCheckBox("Auto-Copy"); self.cCtClipB.setToolTipText("When 'Checked' after the Categories are created they will added to the clipboard") self.cCtClipB.setSelected(1) Larea2 = JLabel("OutputArea:") Sarea2 = JScrollPane() self.area2 = JTextArea() self.area2.setToolTipText("Output Area") self.area2.setEditable(False) self.area2.setBorder(BorderFactory.createLineBorder(Color.gray)) Sarea2.setPreferredSize(Dimension(300,100)) Sarea2.getViewport().setView((self.area2)) ############################################################# # Tabbed Area: tabPane = JTabbedPane(JTabbedPane.TOP) self.getContentPane().add(tabPane) ##################################################### # Text Edit pane panel_TEdit = JPanel() layout2 = GroupLayout(panel_TEdit) layout2.setAutoCreateGaps(True) layout2.setAutoCreateContainerGaps(True) panel_TEdit.setLayout(layout2) bRemoveNBSP_L = JButton("Clean LText", actionPerformed=self.bRemoveNBSP_L) bRemoveNBSP_L.setToolTipText("Removes Spaces, Tabs from the start of every text line from the input Area") bRemoveNBSP_R = JButton("Clean RText", actionPerformed=self.bRemoveNBSP_R) bRemoveNBSP_R.setToolTipText("Removes Spaces, Tabs from the end of every text line from the input Area") self.ReplaceThis = JTextField() self.ReplaceThis = JTextField(maximumSize=Dimension(120,25)) self.ReplaceThis.setToolTipText("Text to be replaced") self.ReplaceThat = JTextField() self.ReplaceThat = JTextField(maximumSize=Dimension(120,25)) self.ReplaceThat.setToolTipText("Text to be placed") bSandReplace = JButton("Replace Text", actionPerformed=self.bSandReplace) bSandReplace.setToolTipText("Replace the text from This with Text from That in the Text from the Input Area and displays it in the Output Area") bRemNumbers = JButton("Rem Numbers", actionPerformed=self.RemNumbers) bRemNumbers.setToolTipText("Removes numbers from the start of every line") ##################################################### # Dimension pane panel_Dimensions = JPanel() layout3 = GroupLayout(panel_Dimensions) layout3.setAutoCreateGaps(True) layout3.setAutoCreateContainerGaps(True) panel_Dimensions.setLayout(layout3) self.cCurly = JCheckBox("Curly"); self.cCurly.setToolTipText("When 'Checked' Curly Brackets will surround the Categories") self.cCurly.setSelected(1) self.cSemiC = JCheckBox("SemiColumn"); self.cSemiC.setToolTipText("When 'Checked' after the Categories are created at the end will be a semicolomn") self.cSemiC.setSelected(1) self.iStart = JTextField(maximumSize=Dimension(40,25)) self.iStart.setToolTipText("The Start Index for the Making of the Categories") self.RThis = JTextField() self.RThis = JTextField(maximumSize=Dimension(120,25)) self.RThis.setToolTipText("The Starting Index used in creating the Categorical") self.RThat = JTextField() self.RThat = JTextField(maximumSize=Dimension(120,25)) self.RThat.setToolTipText("The Finish Index used in creating the Categorical") optioncCategories = JLabel("Options:") bcCat = JButton("CreatCateg", actionPerformed=self.bcCat) bcCat.setToolTipText("Create a categorical form starting C_Index to finish C_Index; Use the text boxes to define the indexes") bM_Categories = JButton("Categories", actionPerformed=self.mCategories) bM_Categories.setToolTipText("Make Categories using the lines from the Input Area. Use it to define Categorical questions.") ##################################################### # ConfirmIt pane panel_ConfirmIt = JPanel() layout4 = GroupLayout(panel_ConfirmIt) layout4.setAutoCreateGaps(True) layout4.setAutoCreateContainerGaps(True) panel_ConfirmIt.setLayout(layout4) self.PID = JTextField() self.PID = JTextField(maximumSize=Dimension(120,25)) self.PID.setToolTipText("The PID number used for creating links with PID and ids from every line of the Input Area") bClinks = JButton("Create Links", actionPerformed=self.bClinks) bClinks.setToolTipText("Create links for a project using PID and ID, ID`s are read from every line of the Input Area") bClinksNA = JButton("Create Links NA ", actionPerformed=self.bClinksNA) bClinksNA.setToolTipText("Create links for a project using PID and ID`s from the standard sample test for US") bClinksCA = JButton("Create Links CA", actionPerformed=self.bClinksCA) bClinksCA.setToolTipText("Create links for a project using PID and ID`s from the standard sample test for CA") self.Width = JTextField() self.Width = JTextField(maximumSize=Dimension(120,25)) self.Width.setToolTipText("The Width used in creating the DIV html tag, note the dimension used is in px") baddDIVt = JButton("Add DIV tag", actionPerformed=self.baddDIVt) baddDIVt.setToolTipText("Create a DIV tag for every line in the Input Area") ##################################################### # Statistics pane panel_Statistics = JPanel() layout5 = GroupLayout(panel_Statistics) layout5.setAutoCreateGaps(True) layout5.setAutoCreateContainerGaps(True) panel_Statistics.setLayout(layout5) ##################################################### # TimeTraking pane panel_TimeTraking = JPanel() layout6 = GroupLayout(panel_TimeTraking) layout6.setAutoCreateGaps(True) layout6.setAutoCreateContainerGaps(True) panel_TimeTraking.setLayout(layout6) ##################################################### # Tabbed Area Tabs tabPane.addTab("Text Edit", panel_TEdit) tabPane.addTab("Dimensions", panel_Dimensions) tabPane.addTab("ConfirmIt", panel_ConfirmIt) tabPane.addTab("Statistics", panel_Statistics) tabPane.addTab("TimeTraking", panel_TimeTraking) ############################################################# ############################################################# # Aplication Layouts: 2 groups one Horizontal and one Vertical ############################################################# # Frame Layout: 2 groups one Horizontal and one Vertical layout.setHorizontalGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup() .addComponent(Larea1) .addComponent(Sarea1) .addComponent(Sarea2) .addGroup(layout.createSequentialGroup() .addComponent(bCopyToInput) .addComponent(bClear) .addComponent(self.cCtClipB)) .addComponent(Larea2)) .addGroup(layout.createParallelGroup() .addComponent(tabPane)) ) layout.setVerticalGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup() .addGroup(layout.createSequentialGroup() .addComponent(Larea1) .addComponent(Sarea1) .addGroup(layout.createParallelGroup() .addComponent(bCopyToInput) .addComponent(bClear) .addComponent(self.cCtClipB) ) .addComponent(Larea2) .addComponent(Sarea2)) .addGroup(layout.createSequentialGroup() .addComponent(tabPane)) ) ) ############################################################# # TEdit Layout: 2 groups one Horizontal and one Vertical layout2.setHorizontalGroup(layout2.createSequentialGroup() .addGroup(layout2.createParallelGroup() .addGroup(layout2.createSequentialGroup() .addComponent(bRemNumbers) .addComponent(bRemoveNBSP_L) .addComponent(bRemoveNBSP_R)) .addGroup(layout2.createSequentialGroup() .addComponent(bSandReplace) .addComponent(self.ReplaceThis) .addComponent(self.ReplaceThat)) )) layout2.setVerticalGroup(layout2.createSequentialGroup() .addGroup(layout2.createParallelGroup() .addComponent(bRemNumbers) .addComponent(bRemoveNBSP_L) .addComponent(bRemoveNBSP_R)) .addGroup(layout2.createParallelGroup() .addComponent(bSandReplace) .addComponent(self.ReplaceThis) .addComponent(self.ReplaceThat)) ) ############################################################# # Dimensions Layout: 2 groups one Horizontal and one Vertical layout3.setHorizontalGroup(layout3.createSequentialGroup() .addGroup(layout3.createParallelGroup() .addGroup(layout3.createSequentialGroup() .addComponent(bM_Categories) .addComponent(self.iStart)) .addGroup(layout3.createSequentialGroup() .addComponent(optioncCategories) .addComponent(self.cCurly) .addComponent(self.cSemiC) ) .addGroup(layout3.createSequentialGroup() .addComponent(bcCat) .addComponent(self.RThis) .addComponent(self.RThat)) .addGroup(layout3.createSequentialGroup() ) ) ) layout3.setVerticalGroup(layout3.createSequentialGroup() .addGroup(layout3.createSequentialGroup() .addGroup(layout3.createParallelGroup() .addComponent(bM_Categories) .addComponent(self.iStart)) .addGroup(layout3.createParallelGroup() .addComponent(bcCat) .addComponent(self.RThis) .addComponent(self.RThat)) .addGroup(layout3.createParallelGroup() .addGroup(layout3.createParallelGroup() .addComponent(optioncCategories) .addComponent(self.cCurly) .addComponent(self.cSemiC) ) ) ) ) ############################################################# # ConfimIT Layout: 2 groups one Horizontal and one Vertical layout4.setHorizontalGroup(layout4.createSequentialGroup() .addGroup(layout4.createParallelGroup() .addGroup(layout4.createSequentialGroup() .addComponent(bClinks) .addComponent(self.PID) ) .addGroup(layout4.createSequentialGroup() .addComponent(bClinksNA) .addComponent(bClinksCA) ) .addGroup(layout4.createSequentialGroup() .addComponent(baddDIVt) .addComponent(self.Width) ) )) layout4.setVerticalGroup(layout4.createSequentialGroup() .addGroup(layout4.createSequentialGroup() .addGroup(layout4.createParallelGroup() .addComponent(bClinks) .addComponent(self.PID)) .addGroup(layout4.createParallelGroup() .addComponent(bClinksNA) .addComponent(bClinksCA) ) .addGroup(layout4.createParallelGroup() .addComponent(baddDIVt) .addComponent(self.Width) ) )) #layout2.linkSize(SwingConstants.HORIZONTAL, [self.cCurly,bM_Categories]) #layout.linkSize(SwingConstants.HORIZONTAL, [ok, bCopyToInput, close, bM_Categories]) #layout3.linkSize(SwingConstants.HORIZONTAL, [self.RThis,self.RThat,bRemoveNBSP_L,bRemoveNBSP_R,bM_Categories,bSandReplace,bcCat]) ############################################################# ############################################################# # Aplication Settings self.pack() #self.setPreferredSize(Dimension(1000, 1000)) self.setTitle("Workhelper") self.setSize(800, 500) self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) self.setLocationRelativeTo(None) self.setVisible(True) ############################################################# ############################################################# # WorkHelper class methods: def onQuit(self, e): "@sig public void setExpression(java.lang.String e)" os.system.exit(0) # def addToClipBoard(self, text): # "@sig public void setExpression(java.lang.String text)" # command = 'echo ' + text.strip() + '| clip' # os.system(command) # brute method for pasting into clipboard on windows def mCategories(self, e): "@sig public void setExpression(java.lang.String e)" """ Takes every line of text form the Input Area and by using a string composition it creates the output in the SPSS dimension categories format. """ try: StartIndex = int(self.iStart.getText()) except ValueError: StartIndex=1 text=self.area1.getText().rstrip() counter=StartIndex lastindex=0 textO="" for i in range(0,len(text)): if text[i]=='\n': textO=textO+("_"+str(counter)+' "'+text[lastindex:i]+'",\n') lastindex=i+1 counter=counter+1 if len(text[lastindex:len(text)])>0: textO=textO+("_"+str(counter)+' "'+text[lastindex:len(text)]+'"') if len(textO)>0: if self.cCurly.isSelected(): textO = "{\n"+ textO + "\n}" if self.cSemiC.isSelected(): textO = textO + ";" self.copyToClipboard(textO) self.area2.setText(textO) def copyToClipboard(self, text): if self.cCtClipB.isSelected(): stringSelection = StringSelection(text) self.clipboard.setContents(stringSelection, None) def bCopyToInput(self, e): "@sig public void setExpression(java.lang.String e)" """Copy the Text from the Output Area to the input Area for further operations""" self.area1.setText(self.area2.getText()) def bRemoveNBSP_L(self, e): "@sig public void setExpression(java.lang.String e)" text=self.area1.getText().rstrip() textO="" lastindex=0 for i in range(0,len(text)): if text[i] == '\n': textO = textO+text[lastindex:i].lstrip()+"\n" lastindex=i+1 #print(text[0:i].lstrip()+'\n') if len(text[lastindex:len(text)])>0: textO=textO+text[lastindex:len(text)].lstrip() self.area2.setText(textO) def bRemoveNBSP_R(self, e): "@sig public void setExpression(java.lang.String e)" text=self.area1.getText().rstrip() textO="" lastindex=0 for i in range(0,len(text)): if text[i] == '\n': textO = textO+text[lastindex:i].rstrip()+"\n" lastindex=i+1 #print(text[0:i].lstrip()+'\n') if len(text[lastindex:len(text)])>0: textO=textO+text[lastindex:len(text)].rstrip() self.area2.setText(textO) def bClear(self, e): "@sig public void setExpression(java.lang.String e)" self.area1.setText("") self.area2.setText("") def bcCat(self, e): "@sig public void setExpression(java.lang.String e)" try: StartIndex = int(self.RThis.getText()) except ValueError: StartIndex=1 try: FinishIndex = int(self.RThat.getText()) except ValueError: FinishIndex=1 cCats="" for i in range(StartIndex,FinishIndex+1): if i<>FinishIndex: cCats=cCats+"_"+str(i)+"," else: cCats=cCats+"_"+str(i) if StartIndex<FinishIndex: cCats="{"+cCats+"}" self.copyToClipboard(cCats) self.area2.setText(cCats) def bSandReplace(self, e): self.area2.setText(self.area1.getText().replace(self.ReplaceThis.getText(),self.ReplaceThat.getText())) self.copyToClipboard(self.area2.getText()) ############################################################# # Confirmit def bClinks(self, e): text=self.area1.getText().rstrip() lastindex=0 textO="" for i in range(0,len(text)): if text[i]=='\n': textO=textO+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+text[lastindex:i]+'\n' lastindex=i+1 if len(text[lastindex:len(text)])>0: textO=textO+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+text[lastindex:len(text)] self.copyToClipboard(textO) self.area2.setText(textO) def bClinksNA(self, e): output="" for i in range (1,201): if i<10: output=output+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+'US9900'+str(i)+'\n' else: if i<100: output=output+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+'US990'+str(i)+'\n' else: if i==200: output=output+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+'US99'+str(i) else: output=output+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+'US99'+str(i)+'\n' self.area2.setText(output) self.copyToClipboard(self.area2.getText()) def bClinksCA(self, e): output="" for i in range (1,201): if i<10: output=output+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+'CA9900'+str(i)+'\n' else: if i<100: output=output+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+'CA990'+str(i)+'\n' else: if i==200: output=output+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+'CA99'+str(i) else: output=output+'http://surveys.ipsosinteractive.com/surveys2/?pid='+self.PID.getText()+'&id='+'CA99'+str(i)+'\n' self.area2.setText(output) self.copyToClipboard(self.area2.getText()) def baddDIVt(self, e): try: Width = int(self.Width.getText()) except ValueError: Width=1 text=self.area1.getText().rstrip() lastindex=0 textO="" for i in range(0,len(text)): if text[i]=='\n': textO=textO+'<div style="width:'+str(Width)+'px">'+text[lastindex:i]+'</div>'+'\n' lastindex=i+1 if len(text[lastindex:len(text)])>0: textO=textO+'<div style="width:'+str(Width)+'px">'+text[lastindex:len(text)]+'</div>' self.copyToClipboard(textO) self.area2.setText(textO) def RemNumbers(self, e): text=self.area1.getText().rstrip() lastindex=0 textO="" for i in range(0,len(text)): if text[i]=='\n': textO=textO+text[lastindex:i].lstrip('1234567890')+'\n' lastindex=i+1 if len(text[lastindex:len(text)])>0: textO=textO+text[lastindex:len(text)].lstrip('1234567890') self.copyToClipboard(textO) self.area2.setText(textO)
class BurpExtender(IBurpExtender, ITab, IMessageEditorController, AbstractTableModel, IContextMenuFactory): def registerExtenderCallbacks(self, callbacks): # keep a reference to our callbacks object self._callbacks = callbacks # obtain an extension helpers object self._helpers = callbacks.getHelpers() # set our extension name callbacks.setExtensionName("PT Vulnerabilities Manager") self.config = SafeConfigParser() self.createSection('projects') self.createSection('general') self.config.read('config.ini') self.chooser = JFileChooser() # create the log and a lock on which to synchronize when adding log entries self._log = ArrayList() self._lock = Lock() self.logTable = Table(self) self.logTable.getColumnModel().getColumn(0).setMaxWidth(35) self.logTable.getColumnModel().getColumn(1).setMinWidth(100) self._requestViewer = self._callbacks.createMessageEditor(self, False) self._responseViewer = self._callbacks.createMessageEditor(self, False) self.initVulnerabilityTab() self.initProjSettingsTab() self.initTabs() self.initCallbacks() if self.projPath.getText() != None: self.loadVulnerabilities(self.projPath.getText()) print "Thank you for installing PT Vulnerabilities Manager v1.0 extension" print "by Barak Tawily\n\n\n" print "Disclaimer:\nThis extension might create folders and files in your hardisk which might be declared as sensitive information, make sure you are creating projects under encrypted partition" return def initVulnerabilityTab(self): # ## init vulnerability tab # nameLabel = JLabel("Vulnerability Name:") nameLabel.setBounds(10, 10, 140, 30) self.addButton = JButton("Add",actionPerformed=self.addVuln) self.addButton.setBounds(10, 500, 100, 30) rmVulnButton = JButton("Remove",actionPerformed=self.rmVuln) rmVulnButton.setBounds(465, 500, 100, 30) mitigationLabel = JLabel("Mitigation:") mitigationLabel.setBounds(10, 290, 150, 30) addSSBtn = JButton("Add SS",actionPerformed=self.addSS) addSSBtn.setBounds(750, 40, 110, 30) deleteSSBtn = JButton("Remove SS",actionPerformed=self.removeSS) deleteSSBtn.setBounds(750, 75, 110, 30) piclistLabel = JLabel("Images list:") piclistLabel.setBounds(580, 10, 140, 30) self.screenshotsList = DefaultListModel() self.ssList = JList(self.screenshotsList) self.ssList.setBounds(580, 40, 150, 250) self.ssList.addListSelectionListener(ssChangedHandler(self)) self.ssList.setBorder(BorderFactory.createLineBorder(Color.GRAY)) previewPicLabel = JLabel("Selected image preview: (click to open in image viewer)") previewPicLabel.setBounds(580, 290, 500, 30) copyImgMenu = JMenuItem("Copy") copyImgMenu.addActionListener(copyImg(self)) self.imgMenu = JPopupMenu("Popup") self.imgMenu.add(copyImgMenu) self.firstPic = JLabel() self.firstPic.setBorder(BorderFactory.createLineBorder(Color.GRAY)) self.firstPic.setBounds(580, 320, 550, 400) self.firstPic.addMouseListener(imageClicked(self)) self.vulnName = JTextField("") self.vulnName.getDocument().addDocumentListener(vulnTextChanged(self)) self.vulnName.setBounds(140, 10, 422, 30) sevirities = ["Unclassified", "Critical","High","Medium","Low"] self.threatLevel = JComboBox(sevirities); self.threatLevel.setBounds(140, 45, 140, 30) colors = ["Color:", "Green", "Red"] self.colorCombo = JComboBox(colors); self.colorCombo.setBounds(465, 45, 100, 30) self.colorCombo severityLabel = JLabel("Threat Level:") severityLabel.setBounds(10, 45, 100, 30) descriptionLabel = JLabel("Description:") descriptionLabel.setBounds(10, 80, 100, 30) self.descriptionString = JTextArea("", 5, 30) self.descriptionString.setWrapStyleWord(True); self.descriptionString.setLineWrap(True) self.descriptionString.setBounds(10, 110, 555, 175) descriptionStringScroll = JScrollPane(self.descriptionString) descriptionStringScroll.setBounds(10, 110, 555, 175) descriptionStringScroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED) self.mitigationStr = JTextArea("", 5, 30) self.mitigationStr.setWrapStyleWord(True); self.mitigationStr.setLineWrap(True) self.mitigationStr.setBounds(10, 320, 555, 175) mitigationStrScroll = JScrollPane(self.mitigationStr) mitigationStrScroll.setBounds(10, 320, 555, 175) mitigationStrScroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED) self.pnl = JPanel() self.pnl.setBounds(0, 0, 1000, 1000); self.pnl.setLayout(None); self.pnl.add(addSSBtn) self.pnl.add(piclistLabel) self.pnl.add(nameLabel) self.pnl.add(deleteSSBtn) self.pnl.add(rmVulnButton) self.pnl.add(severityLabel) self.pnl.add(mitigationLabel) self.pnl.add(descriptionLabel) self.pnl.add(previewPicLabel) self.pnl.add(mitigationStrScroll) self.pnl.add(descriptionStringScroll) self.pnl.add(self.ssList) self.pnl.add(self.firstPic) self.pnl.add(self.addButton) self.pnl.add(self.vulnName) self.pnl.add(self.threatLevel) self.pnl.add(self.colorCombo) def initProjSettingsTab(self): # init project settings projNameLabel = JLabel("Name:") projNameLabel.setBounds(10, 50, 140, 30) self.projName = JTextField("") self.projName.setBounds(140, 50, 320, 30) self.projName.getDocument().addDocumentListener(projTextChanged(self)) detailsLabel = JLabel("Details:") detailsLabel.setBounds(10, 120, 140, 30) reportLabel = JLabel("Generate Report:") reportLabel.setBounds(10, 375, 140, 30) types = ["DOCX","HTML","XLSX"] self.reportType = JComboBox(types) self.reportType.setBounds(10, 400, 140, 30) generateReportButton = JButton("Generate", actionPerformed=self.generateReport) generateReportButton.setBounds(160, 400, 90, 30) self.projDetails = JTextArea("", 5, 30) self.projDetails.setWrapStyleWord(True); self.projDetails.setLineWrap(True) projDetailsScroll = JScrollPane(self.projDetails) projDetailsScroll.setBounds(10, 150, 450, 175) projDetailsScroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED) projPathLabel = JLabel("Path:") projPathLabel.setBounds(10, 90, 140, 30) self.projPath = JTextField("") self.projPath.setBounds(140, 90, 320, 30) chooseProjPathButton = JButton("Browse...",actionPerformed=self.chooseProjPath) chooseProjPathButton.setBounds(470, 90, 100, 30) importProjButton = JButton("Import",actionPerformed=self.importProj) importProjButton.setBounds(470, 10, 100, 30) exportProjButton = JButton("Export",actionPerformed=self.exportProj) exportProjButton.setBounds(575, 10, 100, 30) openProjButton = JButton("Open Directory",actionPerformed=self.openProj) openProjButton.setBounds(680, 10, 130, 30) currentProjectLabel = JLabel("Current:") currentProjectLabel.setBounds(10, 10, 140, 30) projects = self.config.options('projects') self.currentProject = JComboBox(projects) self.currentProject.addActionListener(projectChangeHandler(self)) self.currentProject.setBounds(140, 10, 140, 30) self.autoSave = JCheckBox("Auto Save Mode") self.autoSave.setEnabled(False) # implement this feature self.autoSave.setBounds(300, 10, 140, 30) self.autoSave.setToolTipText("Will save any changed value while focus is out") addProjButton = JButton("Add / Update",actionPerformed=self.addProj) addProjButton.setBounds(10, 330, 150, 30) removeProjButton = JButton("Remove Current",actionPerformed=self.rmProj) removeProjButton.setBounds(315, 330, 146, 30) generalOptions = self.config.options('general') if 'default project' in generalOptions: defaultProj = self.config.get('general','default project') self.currentProject.getModel().setSelectedItem(defaultProj) self.projPath.setText(self.config.get('projects',self.currentProject.getSelectedItem())) self.clearProjTab = True self.projectSettings = JPanel() self.projectSettings.setBounds(0, 0, 1000, 1000) self.projectSettings.setLayout(None) self.projectSettings.add(reportLabel) self.projectSettings.add(detailsLabel) self.projectSettings.add(projPathLabel) self.projectSettings.add(addProjButton) self.projectSettings.add(openProjButton) self.projectSettings.add(projNameLabel) self.projectSettings.add(projDetailsScroll) self.projectSettings.add(importProjButton) self.projectSettings.add(exportProjButton) self.projectSettings.add(removeProjButton) self.projectSettings.add(generateReportButton) self.projectSettings.add(chooseProjPathButton) self.projectSettings.add(currentProjectLabel) self.projectSettings.add(self.projPath) self.projectSettings.add(self.autoSave) self.projectSettings.add(self.projName) self.projectSettings.add(self.reportType) self.projectSettings.add(self.currentProject) def initTabs(self): # ## init autorize tabs # self._splitpane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT) self.scrollPane = JScrollPane(self.logTable) self._splitpane.setLeftComponent(self.scrollPane) colorsMenu = JMenu("Paint") redMenu = JMenuItem("Red") noneMenu = JMenuItem("None") greenMenu = JMenuItem("Green") redMenu.addActionListener(paintChange(self, "Red")) noneMenu.addActionListener(paintChange(self, None)) greenMenu.addActionListener(paintChange(self, "Green")) colorsMenu.add(redMenu) colorsMenu.add(noneMenu) colorsMenu.add(greenMenu) self.menu = JPopupMenu("Popup") self.menu.add(colorsMenu) self.tabs = JTabbedPane() self.tabs.addTab("Request", self._requestViewer.getComponent()) self.tabs.addTab("Response", self._responseViewer.getComponent()) self.tabs.addTab("Vulnerability", self.pnl) self.tabs.addTab("Project Settings", self.projectSettings) self.tabs.setSelectedIndex(2) self._splitpane.setRightComponent(self.tabs) def initCallbacks(self): # ## init callbacks # # customize our UI components self._callbacks.customizeUiComponent(self._splitpane) self._callbacks.customizeUiComponent(self.logTable) self._callbacks.customizeUiComponent(self.scrollPane) self._callbacks.customizeUiComponent(self.tabs) self._callbacks.registerContextMenuFactory(self) # add the custom tab to Burp's UI self._callbacks.addSuiteTab(self) def loadVulnerabilities(self, projPath): self.clearList(None) selected = False for root, dirs, files in os.walk(projPath): # make it go only for dirs for dirName in dirs: xmlPath = projPath+"/"+dirName+"/vulnerability.xml" # xmlPath = xmlPath.replace("/","//") document = self.getXMLDoc(xmlPath) nodeList = document.getDocumentElement().getChildNodes() vulnName = nodeList.item(0).getTextContent() severity = nodeList.item(1).getTextContent() description = nodeList.item(2).getTextContent() mitigation = nodeList.item(3).getTextContent() color = nodeList.item(4).getTextContent() test = vulnerability(vulnName,severity,description,mitigation,color) self._lock.acquire() row = self._log.size() self._log.add(test) self.fireTableRowsInserted(row, row) self._lock.release() if vulnName == self.vulnName.getText(): self.logTable.setRowSelectionInterval(row,row) selected = True if selected == False and self._log.size() > 0: self.logTable.setRowSelectionInterval(0, 0) self.loadVulnerability(self._log.get(0)) def createSection(self, sectioName): self.config.read('config.ini') if not (sectioName in self.config.sections()): self.config.add_section(sectioName) cfgfile = open("config.ini",'w') self.config.write(cfgfile) cfgfile.close() def saveCfg(self): f = open('config.ini', 'w') self.config.write(f) f.close() def getXMLDoc(self, xmlPath): try: document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xmlPath) return document except: self._extender.popup("XML file not found") return def saveXMLDoc(self, doc, xmlPath): transformerFactory = TransformerFactory.newInstance() transformer = transformerFactory.newTransformer() source = DOMSource(doc) result = StreamResult(File(xmlPath)) transformer.transform(source, result) def generateReport(self,event): if self.reportType.getSelectedItem() == "HTML": path = self.reportToHTML() if self.reportType.getSelectedItem() == "XLSX": path = self.reportToXLS() if self.reportType.getSelectedItem() == "DOCX": path = self.generateReportFromDocxTemplate('template.docx',"newfile.docx", 'word/document.xml') n = JOptionPane.showConfirmDialog(None, "Report generated successfuly:\n%s\nWould you like to open it?" % (path), "PT Manager", JOptionPane.YES_NO_OPTION) if n == JOptionPane.YES_OPTION: os.system('"' + path + '"') # Bug! stucking burp until the file get closed def exportProj(self,event): self.chooser.setDialogTitle("Save project") Ffilter = FileNameExtensionFilter("Zip files", ["zip"]) self.chooser.setFileFilter(Ffilter) returnVal = self.chooser.showSaveDialog(None) if returnVal == JFileChooser.APPROVE_OPTION: dst = str(self.chooser.getSelectedFile()) shutil.make_archive(dst,"zip",self.getCurrentProjPath()) self.popup("Project export successfuly") def importProj(self,event): self.chooser.setDialogTitle("Select project zip to directory") Ffilter = FileNameExtensionFilter("Zip files", ["zip"]) self.chooser.setFileFilter(Ffilter) returnVal = self.chooser.showOpenDialog(None) if returnVal == JFileChooser.APPROVE_OPTION: zipPath = str(self.chooser.getSelectedFile()) self.chooser.setDialogTitle("Select project directory") self.chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY) returnVal = self.chooser.showOpenDialog(None) if returnVal == JFileChooser.APPROVE_OPTION: projPath = str(self.chooser.getSelectedFile()) + "/PTManager" with zipfile.ZipFile(zipPath, "r") as z: z.extractall(projPath) xmlPath = projPath + "/project.xml" document = self.getXMLDoc(xmlPath) nodeList = document.getDocumentElement().getChildNodes() projName = nodeList.item(0).getTextContent() nodeList.item(1).setTextContent(projPath) self.saveXMLDoc(document, xmlPath) self.config.set('projects', projName, projPath) self.saveCfg() self.reloadProjects() self.currentProject.getModel().setSelectedItem(projName) self.clearVulnerabilityTab() def reportToXLS(self): if not xlsxwriterImported: self.popup("xlsxwriter library is not imported") return workbook = xlsxwriter.Workbook(self.getCurrentProjPath() + '/PT Manager Report.xlsx') worksheet = workbook.add_worksheet() bold = workbook.add_format({'bold': True}) worksheet.write(0, 0, "Vulnerability Name", bold) worksheet.write(0, 1, "Threat Level", bold) worksheet.write(0, 2, "Description", bold) worksheet.write(0, 3, "Mitigation", bold) row = 1 for i in range(0,self._log.size()): worksheet.write(row, 0, self._log.get(i).getName()) worksheet.write(row, 1, self._log.get(i).getSeverity()) worksheet.write(row, 2, self._log.get(i).getDescription()) worksheet.write(row, 3, self._log.get(i).getMitigation()) row = row + 1 # add requests and images as well workbook.close() return self.getCurrentProjPath() + '/PT Manager Report.xlsx' def reportToHTML(self): htmlContent = """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="he" dir="ltr"> <head> <title>PT Manager Report</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <style> body { background-repeat: no-repeat; background-attachment: fixed; font-family: Arial,Tahoma,sens-serif; font-size: 13px; margin: auto; } #warpcenter { width: 900px; margin: 0px auto; } table { border: 2px dashed #000000; } td { border-top: 2px dashed #000000; padding: 10px; } img { border: 0px; } </style> <script language="javascript"> function divHideShow(divToHideOrShow) { var div = document.getElementById(divToHideOrShow); if (div.style.display == "block") { div.style.display = "none"; } else { div.style.display = "block"; } } </script> </head> <body> <div id="warpcenter"> <h1> PT Manager Report </h1> <h2> Project: %s</h1> """ % (self.projName.getText()) for i in range(0,self._log.size()): name = self._log.get(i).getName() request = "None" response = "None" path = self.getVulnReqResPath("request",name) if os.path.exists(path): request = self.newlineToBR(self.getFileContent(path)) path = self.getVulnReqResPath("response",name) if os.path.exists(path): response = self.newlineToBR(self.getFileContent(path)) images = "" for fileName in os.listdir(self.projPath.getText()+"/"+self.clearStr(name)): if fileName.endswith(".jpg"): images += "%s<br><img src=\"%s\"><br><br>" % (fileName, self.projPath.getText()+"/"+self.clearStr(name) + "/" + fileName) description = self.newlineToBR(self._log.get(i).getDescription()) mitigation = self.newlineToBR(self._log.get(i).getMitigation()) htmlContent += self.convertVulntoTable(i,name,self._log.get(i).getSeverity(), description,mitigation, request, response, images) htmlContent += "</div></body></html>" f = open(self.getCurrentProjPath() + '/PT Manager Report.html', 'w') f.writelines(htmlContent) f.close() return self.getCurrentProjPath() + '/PT Manager Report.html' def newlineToBR(self,string): return "<br />".join(string.split("\n")) def getFileContent(self,path): f = open(path, "rb") content = f.read() f.close() return content def convertVulntoTable(self, number, name, severity, description, mitigation, request = "None", response = "None", images = "None"): return """<div style="width: 100%%;height: 30px;text-align: center;background-color:#E0E0E0;font-size: 17px;font-weight: bold;color: #000;padding-top: 10px;">%s <a href="javascript:divHideShow('Table_%s');" style="color:#191970">(OPEN / CLOSE)</a></div> <div id="Table_%s" style="display: none;"> <table width="100%%" cellspacing="0" cellpadding="0" style="margin: 0px auto;text-align: left;border-top: 0px;"> <tr> <td> <div style="font-size: 16px;font-weight: bold;"> <span style="color:#000000">Threat Level: </span> <span style="color:#8b8989">%s</span> </td> </tr> <tr> <td> <div style="font-size: 16px;font-weight: bold;"> <span style="color:#000000">Description</span> <a href="javascript:divHideShow('Table_%s_Command_03');" style="color:#191970">OPEN / CLOSE >>></a> </div> <div id="Table_%s_Command_03" style="display: none;margin-top: 25px;"> %s </div> </td> </tr> <tr> <td> <div style="font-size: 16px;font-weight: bold;"> <span style="color:#000000">Mitigration</span> <a href="javascript:divHideShow('Table_%s_Command_04');" style="color:#191970">OPEN / CLOSE >>></a> </div> <div id="Table_%s_Command_04" style="display: none;margin-top: 25px;"> %s <b> </td> </tr> <tr> <td> <div style="font-size: 16px;font-weight: bold;"> <span style="color:#000000">Request</span> <a href="javascript:divHideShow('Table_%s_Command_05');" style="color:#191970">OPEN / CLOSE >>></a> </div> <div id="Table_%s_Command_05" style="display: none;margin-top: 25px;"> %s <b> </td> </tr> <tr> <td> <div style="font-size: 16px;font-weight: bold;"> <span style="color:#000000">Response</span> <a href="javascript:divHideShow('Table_%s_Command_06');" style="color:#191970">OPEN / CLOSE >>></a> </div> <div id="Table_%s_Command_06" style="display: none;margin-top: 25px;"> %s <b> </td> </tr> <tr> <td> <div style="font-size: 16px;font-weight: bold;"> <span style="color:#000000">Images</span> <a href="javascript:divHideShow('Table_%s_Command_07');" style="color:#191970">OPEN / CLOSE >>></a> </div> <div id="Table_%s_Command_07" style="display: none;margin-top: 25px;"> %s <b> </td> </tr> </table> </div><br><br>""" % (name,number,number,severity,number,number,description,number,number,mitigation,number,number,request,number,number,response,number,number,images) def clearVulnerabilityTab(self, rmVuln=True): if rmVuln: self.vulnName.setText("") self.descriptionString.setText("") self.mitigationStr.setText("") self.colorCombo.setSelectedIndex(0) self.threatLevel.setSelectedIndex(0) self.screenshotsList.clear() self.addButton.setText("Add") self.firstPic.setIcon(None) def saveRequestResponse(self, type, requestResponse, vulnName): path = self.getVulnReqResPath(type,vulnName) f = open(path, 'wb') f.write(requestResponse) f.close() def openProj(self, event): os.system('explorer ' + self.projPath.getText()) def getVulnReqResPath(self, requestOrResponse, vulnName): return self.getCurrentProjPath() + "/" + self.clearStr(vulnName) + "/"+requestOrResponse+"_" + self.clearStr(vulnName) def htmlEscape(self,data): return data.replace('&', '&').replace('<', '<').replace('>', '>').replace('"', '"').replace("'", ''') def generateReportFromDocxTemplate(self, zipname, newZipName, filename): newZipName = self.getCurrentProjPath() + "/" + newZipName with zipfile.ZipFile(zipname, 'r') as zin: with zipfile.ZipFile(newZipName, 'w') as zout: zout.comment = zin.comment for item in zin.infolist(): if item.filename != filename: zout.writestr(item, zin.read(item.filename)) else: xml_content = zin.read(item.filename) result = re.findall("(.*)<w:body>(?:.*)<\/w:body>(.*)",xml_content)[0] newXML = result[0] templateBody = re.findall("<w:body>(.*)<\/w:body>", xml_content)[0] newBody = "" for i in range(0,self._log.size()): tmp = templateBody tmp = tmp.replace("$vulnerability", self.htmlEscape(self._log.get(i).getName())) tmp = tmp.replace("$severity", self.htmlEscape(self._log.get(i).getSeverity())) tmp = tmp.replace("$description", self.htmlEscape(self._log.get(i).getDescription())) tmp = tmp.replace("$mitigation", self.htmlEscape(self._log.get(i).getMitigation())) newBody = newBody + tmp newXML = newXML + newBody newXML = newXML + result[1] with zipfile.ZipFile(newZipName, mode='a', compression=zipfile.ZIP_DEFLATED) as zf: zf.writestr(filename, newXML) return newZipName def chooseProjPath(self, event): self.chooser.setDialogTitle("Select target directory") self.chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY) returnVal = self.chooser.showOpenDialog(None) if returnVal == JFileChooser.APPROVE_OPTION: projPath = str(self.chooser.getSelectedFile()) + "/PTManager" os.makedirs(projPath) self.projPath.setText(projPath) def reloadProjects(self): self.currentProject.setModel(DefaultComboBoxModel(self.config.options('projects'))) def rmProj(self, event): if self.popUpAreYouSure() == JOptionPane.YES_OPTION: self._requestViewer.setMessage("None", False) self._responseViewer.setMessage("None", False) shutil.rmtree(self.projPath.getText()) self.config.remove_option('projects',self.currentProject.getSelectedItem()) self.reloadProjects() self.currentProject.setSelectedIndex(0) self.loadVulnerabilities(self.projPath.getText()) def popup(self,msg): JOptionPane.showMessageDialog(None,msg) def addProj(self, event): projPath = self.projPath.getText() if projPath == None or projPath == "": self.popup("Please select path") return self.config.set('projects', self.projName.getText(), projPath) self.saveCfg() xml = ET.Element('project') name = ET.SubElement(xml, "name") path = ET.SubElement(xml, "path") details = ET.SubElement(xml, "details") autoSaveMode = ET.SubElement(xml, "autoSaveMode") name.text = self.projName.getText() path.text = projPath details.text = self.projDetails.getText() autoSaveMode.text = str(self.autoSave.isSelected()) tree = ET.ElementTree(xml) try: tree.write(self.getCurrentProjPath()+'/project.xml') except: self.popup("Invalid path") return self.reloadProjects() self.clearVulnerabilityTab() self.clearList(None) self.currentProject.getModel().setSelectedItem(self.projName.getText()) def resize(self, image, width, height): bi = BufferedImage(width, height, BufferedImage.TRANSLUCENT) g2d = bi.createGraphics() g2d.addRenderingHints(RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY)) g2d.drawImage(image, 0, 0, width, height, None) g2d.dispose() return bi; def clearStr(self, var): return var.replace(" " , "_").replace("\\" , "").replace("/" , "").replace(":" , "").replace("*" , "").replace("?" , "").replace("\"" , "").replace("<" , "").replace(">" , "").replace("|" , "").replace("(" , "").replace(")" , "") def popUpAreYouSure(self): dialogResult = JOptionPane.showConfirmDialog(None,"Are you sure?","Warning",JOptionPane.YES_NO_OPTION) if dialogResult == 0: return 0 return 1 def removeSS(self,event): if self.popUpAreYouSure() == JOptionPane.YES_OPTION: os.remove(self.getCurrentVulnPath() + "/" + self.ssList.getSelectedValue()) self.ssList.getModel().remove(self.ssList.getSelectedIndex()) self.firstPic.setIcon(ImageIcon(None)) # check if there is images and select the first one # bug in linux def addSS(self,event): clipboard = Toolkit.getDefaultToolkit().getSystemClipboard() try: image = clipboard.getData(DataFlavor.imageFlavor) except: self.popup("Clipboard not contains image") return vulnPath = self.projPath.getText() + "/" + self.clearStr(self.vulnName.getText()) if not os.path.exists(vulnPath): os.makedirs(vulnPath) name = self.clearStr(self.vulnName.getText()) + str(random.randint(1, 99999))+".jpg" fileName = self.projPath.getText()+"/"+ self.clearStr(self.vulnName.getText()) + "/" + name file = File(fileName) bufferedImage = BufferedImage(image.getWidth(None), image.getHeight(None), BufferedImage.TYPE_INT_RGB); g = bufferedImage.createGraphics(); g.drawImage(image, 0, 0, bufferedImage.getWidth(), bufferedImage.getHeight(), Color.WHITE, None); ImageIO.write(bufferedImage, "jpg", file) self.addVuln(self) self.ssList.setSelectedValue(name,True) def rmVuln(self, event): if self.popUpAreYouSure() == JOptionPane.YES_OPTION: self._requestViewer.setMessage("None", False) self._responseViewer.setMessage("None", False) shutil.rmtree(self.getCurrentVulnPath()) self.clearVulnerabilityTab() self.loadVulnerabilities(self.getCurrentProjPath()) def addVuln(self, event): if self.colorCombo.getSelectedItem() == "Color:": colorTxt = None else: colorTxt = self.colorCombo.getSelectedItem() self._lock.acquire() row = self._log.size() vulnObject = vulnerability(self.vulnName.getText(),self.threatLevel.getSelectedItem(),self.descriptionString.getText(),self.mitigationStr.getText() ,colorTxt) self._log.add(vulnObject) self.fireTableRowsInserted(row, row) self._lock.release() vulnPath = self.projPath.getText() + "/" + self.clearStr(self.vulnName.getText()) if not os.path.exists(vulnPath): os.makedirs(vulnPath) xml = ET.Element('vulnerability') name = ET.SubElement(xml, "name") severity = ET.SubElement(xml, "severity") description = ET.SubElement(xml, "description") mitigation = ET.SubElement(xml, "mitigation") color = ET.SubElement(xml, "color") name.text = self.vulnName.getText() severity.text = self.threatLevel.getSelectedItem() description.text = self.descriptionString.getText() mitigation.text = self.mitigationStr.getText() color.text = colorTxt tree = ET.ElementTree(xml) tree.write(vulnPath+'/vulnerability.xml') self.loadVulnerabilities(self.getCurrentProjPath()) self.loadVulnerability(vulnObject) def vulnNameChanged(self): if os.path.exists(self.getCurrentVulnPath()) and self.vulnName.getText() != "": self.addButton.setText("Update") elif self.addButton.getText() != "Add": options = ["Create a new vulnerability", "Change current vulnerability name"] n = JOptionPane.showOptionDialog(None, "Would you like to?", "Vulnerability Name", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, None, options, options[0]); if n == 0: self.clearVulnerabilityTab(False) self.addButton.setText("Add") else: newName = JOptionPane.showInputDialog( None, "Enter new name:", "Vulnerability Name", JOptionPane.PLAIN_MESSAGE, None, None, self.vulnName.getText()) row = self.logTable.getSelectedRow() old = self.logTable.getValueAt(row,1) self.changeVulnName(newName,old) def changeVulnName(self,new,old): newpath = self.getCurrentProjPath() + "/" + new oldpath = self.getCurrentProjPath() + "/" + old os.rename(oldpath,newpath) self.changeCurrentVuln(new,0, newpath + "/vulnerability.xml") def getCurrentVulnPath(self): return self.projPath.getText() + "/" + self.clearStr(self.vulnName.getText()) def getCurrentProjPath(self): return self.projPath.getText() def loadSS(self, imgPath): image = ImageIO.read(File(imgPath)) if image.getWidth() <= 550 and image.getHeight() <= 400: self.firstPic.setIcon(ImageIcon(image)) self.firstPic.setSize(image.getWidth(),image.getHeight()) else: self.firstPic.setIcon(ImageIcon(self.resize(image,550, 400))) self.firstPic.setSize(550,400) def clearProjectTab(self): self.projPath.setText("") self.projDetails.setText("") def clearList(self, event): self._lock.acquire() self._log = ArrayList() row = self._log.size() self.fireTableRowsInserted(row, row) self._lock.release() # # implement IContextMenuFactory # def createMenuItems(self, invocation): responses = invocation.getSelectedMessages(); if responses > 0: ret = LinkedList() requestMenuItem = JMenuItem("Send to PT Manager"); requestMenuItem.addActionListener(handleMenuItems(self,responses[0], "request")) ret.add(requestMenuItem); return(ret); return null; # # implement ITab # def getTabCaption(self): return "PT Manager" def getUiComponent(self): return self._splitpane # # extend AbstractTableModel # def getRowCount(self): try: return self._log.size() except: return 0 def getColumnCount(self): return 3 def getColumnName(self, columnIndex): if columnIndex == 0: return "#" if columnIndex == 1: return "Vulnerability Name" if columnIndex == 2: return "Threat Level" return "" def getValueAt(self, rowIndex, columnIndex): vulnObject = self._log.get(rowIndex) if columnIndex == 0: return rowIndex+1 if columnIndex == 1: return vulnObject.getName() if columnIndex == 2: return vulnObject.getSeverity() if columnIndex == 3: return vulnObject.getMitigation() if columnIndex == 4: return vulnObject.getColor() return "" def changeCurrentVuln(self,value,fieldNumber, xmlPath = "def"): if xmlPath == "def": xmlPath = self.getCurrentVulnPath() + "/vulnerability.xml" document = self.getXMLDoc(xmlPath) nodeList = document.getDocumentElement().getChildNodes() nodeList.item(fieldNumber).setTextContent(value) self.saveXMLDoc(document, xmlPath) self.loadVulnerabilities(self.getCurrentProjPath()) def loadVulnerability(self, vulnObject): self.addButton.setText("Update") self.vulnName.setText(vulnObject.getName()) self.threatLevel.setSelectedItem(vulnObject.getSeverity()) self.descriptionString.setText(vulnObject.getDescription()) self.mitigationStr.setText(vulnObject.getMitigation()) if vulnObject.getColor() == "" or vulnObject.getColor() == None: self.colorCombo.setSelectedItem("Color:") else: self.colorCombo.setSelectedItem(vulnObject.getColor()) self.screenshotsList.clear() for fileName in os.listdir(self.projPath.getText()+"/"+self.clearStr(vulnObject.getName())): if fileName.endswith(".jpg"): self.screenshotsList.addElement(fileName) imgPath = self.projPath.getText()+"/"+self.clearStr(vulnObject.getName())+'/'+fileName # imgPath = imgPath.replace("/","//") self.loadSS(imgPath) if (self.screenshotsList.getSize() == 0): self.firstPic.setIcon(None) else: self.ssList.setSelectedIndex(0) path = self.getVulnReqResPath("request",vulnObject.getName()) if os.path.exists(path): f = self.getFileContent(path) self._requestViewer.setMessage(f, False) else: self._requestViewer.setMessage("None", False) path = self.getVulnReqResPath("response",vulnObject.getName()) if os.path.exists(path): f = self.getFileContent(path) self._responseViewer.setMessage(f, False) else: self._responseViewer.setMessage("None", False)