Projects STRLCPY LoggerPlusPlus Commits 5942db8b
🤬
  • ■ ■ ■ ■
    CHANGELOG
    1 1  v 3.15
    2 2  =========================================================================
    3 3  BETA
    4  -- Fix "Autosave as CSV"
     4 +- Fix "Autosave as CSV".
     5 +- Huge Refactor.
     6 +- Yet more concurrency fixes.
     7 +- Rewrote export mechanism to be more generic.
    5 8   
    6 9  v 3.14
    7 10  =========================================================================
    skipped 235 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/LoggerPlusPlus.java
    skipped 4 lines
    5 5  import burp.IExtensionStateListener;
    6 6  import com.coreyd97.BurpExtenderUtilities.DefaultGsonProvider;
    7 7  import com.coreyd97.BurpExtenderUtilities.IGsonProvider;
     8 +import com.nccgroup.loggerplusplus.exports.ExportController;
    8 9  import com.nccgroup.loggerplusplus.filterlibrary.FilterLibraryController;
    9 10  import com.nccgroup.loggerplusplus.grepper.GrepperController;
     11 +import com.nccgroup.loggerplusplus.logentry.LogEntry;
    10 12  import com.nccgroup.loggerplusplus.logging.LoggingController;
    11 13  import com.nccgroup.loggerplusplus.logview.LogViewController;
    12 14  import com.nccgroup.loggerplusplus.logview.processor.LogProcessor;
    skipped 4 lines
    17 19   
    18 20  import javax.swing.*;
    19 21  import java.net.URL;
     22 +import java.util.List;
    20 23   
    21 24  import static com.nccgroup.loggerplusplus.util.Globals.PREF_RESTRICT_TO_SCOPE;
    22 25   
    skipped 7 lines
    30 33   private final IGsonProvider gsonProvider;
    31 34   private LoggingController loggingController;
    32 35   private LogProcessor logProcessor;
     36 + private ExportController exportController;
    33 37   private PreferencesController preferencesController;
    34 38   private LogViewController logViewController;
    35 39   private FilterLibraryController libraryController;
    skipped 29 lines
    65 69   
    66 70   loggingController = new LoggingController(this);
    67 71   preferencesController = new PreferencesController(this, loggingController);
     72 + exportController = new ExportController(this, preferencesController.getPreferences());
    68 73   libraryController = new FilterLibraryController(this, preferencesController);
    69 74   logViewController = new LogViewController(this, libraryController);
    70  - logProcessor = new LogProcessor(this, logViewController.getLogTableController());
     75 + logProcessor = new LogProcessor(this, logViewController.getLogTableController(), exportController);
    71 76   grepperController = new GrepperController(this, logViewController.getLogTableController(), preferencesController);
    72 77   contextMenuFactory = new LoggerContextMenuFactory(this);
    73 78   
    skipped 87 lines
    161 166   
    162 167   public LoggerMenu getLoggerMenu() {
    163 168   return loggerMenu;
     169 + }
     170 + 
     171 + public List<LogEntry> getLogEntries(){
     172 + return logViewController.getLogTableController().getLogTableModel().getData();
     173 + }
     174 + 
     175 + public ExportController getExportController() {
     176 + return exportController;
    164 177   }
    165 178  }
    166 179   
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/exports/CSVExporter.java
     1 +package com.nccgroup.loggerplusplus.exports;
     2 + 
     3 +import com.coreyd97.BurpExtenderUtilities.Preferences;
     4 +import com.nccgroup.loggerplusplus.logentry.LogEntry;
     5 +import com.nccgroup.loggerplusplus.logentry.LogEntryField;
     6 +import com.nccgroup.loggerplusplus.logentry.Status;
     7 +import com.nccgroup.loggerplusplus.util.FieldSelectorDialog;
     8 +import com.nccgroup.loggerplusplus.util.Globals;
     9 +import org.apache.commons.text.StringEscapeUtils;
     10 + 
     11 +import javax.swing.*;
     12 +import javax.swing.filechooser.FileNameExtensionFilter;
     13 +import java.io.*;
     14 +import java.util.List;
     15 +import java.util.concurrent.LinkedBlockingQueue;
     16 + 
     17 +/**
     18 + * Created by corey on 21/08/17.
     19 + */
     20 +public class CSVExporter extends LogExporter {
     21 + 
     22 + private final CSVExporterControlPanel controlPanel;
     23 + 
     24 + private FileWriter autoSaveWriter;
     25 + private File autoSaveFile;
     26 + private List<LogEntryField> fields;
     27 + private List<LogEntryField> previousFields;
     28 + private Thread exporterThread;
     29 + private LinkedBlockingQueue<LogEntry> awaitingExport;
     30 + 
     31 + 
     32 + public CSVExporter(ExportController exportController, Preferences preferences){
     33 + super(exportController, preferences);
     34 + this.previousFields = preferences.getSetting(Globals.PREF_PREVIOUS_CSV_FIELDS);
     35 + this.controlPanel = new CSVExporterControlPanel(this);
     36 + }
     37 + 
     38 + @Override
     39 + public void setup() throws Exception {
     40 + fields = showFieldChooserDialog();
     41 + autoSaveFile = getSaveFile("LoggerPlusPlus_Autosave.csv");
     42 + boolean append;
     43 + if(autoSaveFile.exists()){
     44 + append = shouldAppendToExistingFile(autoSaveFile, fields);
     45 + }else{
     46 + append = true;
     47 + }
     48 + 
     49 + autoSaveWriter = new FileWriter(autoSaveFile, append);
     50 + awaitingExport = new LinkedBlockingQueue<>();
     51 + 
     52 + exporterThread = new Thread(() -> {
     53 + if(!append){
     54 + try {
     55 + autoSaveWriter.append(buildHeader(fields));
     56 + autoSaveWriter.flush();
     57 + }catch (IOException e){}
     58 + }
     59 + 
     60 + while(!Thread.currentThread().isInterrupted()){
     61 + try {
     62 + LogEntry logEntry = awaitingExport.take();
     63 + 
     64 + autoSaveWriter.append("\n");
     65 + autoSaveWriter.append(entryToCSVString(logEntry, fields));
     66 + autoSaveWriter.flush();
     67 + 
     68 + }catch (InterruptedException e){
     69 + //Thread stopped
     70 + } catch (IOException e) {
     71 + e.printStackTrace();
     72 + }
     73 + }
     74 + });
     75 + 
     76 + exporterThread.start();
     77 + }
     78 + 
     79 + @Override
     80 + public void shutdown() throws Exception {
     81 + exporterThread.interrupt();
     82 + exporterThread = null;
     83 + try {
     84 + autoSaveWriter.close();
     85 + }catch (IOException ignored){}
     86 + 
     87 + awaitingExport.clear();
     88 + awaitingExport = null;
     89 + autoSaveWriter = null;
     90 + }
     91 + 
     92 + @Override
     93 + public JComponent getExportPanel() {
     94 + return this.controlPanel;
     95 + }
     96 + 
     97 + 
     98 + public List<LogEntryField> showFieldChooserDialog() throws Exception {
     99 + //TODO Display dialog using previously used fields as default
     100 + FieldSelectorDialog fieldSelectorDialog = new FieldSelectorDialog(JOptionPane.getFrameForComponent(this.controlPanel), "CSV Export", previousFields);
     101 + fieldSelectorDialog.setVisible(true);
     102 + 
     103 + List<LogEntryField> selectedFields = fieldSelectorDialog.getSelectedFields();
     104 + if(selectedFields == null || selectedFields.isEmpty()) throw new Exception("Operation cancelled.");
     105 + 
     106 + previousFields = selectedFields;
     107 + preferences.setSetting(Globals.PREF_PREVIOUS_CSV_FIELDS, previousFields);
     108 + 
     109 + return selectedFields;
     110 + }
     111 + 
     112 + static File getSaveFile(String filename) throws Exception {
     113 + JFileChooser chooser = null;
     114 + FileNameExtensionFilter filter = new FileNameExtensionFilter("Excel Format (CSV)", "csv");
     115 + 
     116 + chooser = new JFileChooser();
     117 + chooser.setDialogTitle("Saving Logger++ Entries");
     118 + chooser.setFileFilter(filter);
     119 + chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
     120 + chooser.setSelectedFile(new File(filename));
     121 + chooser.setAcceptAllFileFilterUsed(false);
     122 + 
     123 + int val = chooser.showSaveDialog(null);
     124 + 
     125 + if (val == JFileChooser.APPROVE_OPTION) {
     126 + return chooser.getSelectedFile();
     127 + }
     128 + 
     129 + throw new Exception("Operation cancelled.");
     130 + }
     131 + 
     132 + static boolean shouldAppendToExistingFile(File file, List<LogEntryField> fields) throws Exception{
     133 + if (validHeader(file, fields)) {
     134 + //The existing file uses the same field set.
     135 + // We can ask the user if they want to append the entries or overwrite
     136 + //True = append, false = overwrite.
     137 + return promptAppendToExistingFileDialog();
     138 + } else {
     139 + //Prompt the user if they wish to overwrite
     140 + if(shouldOverwriteExistingFilePrompt()){
     141 + return false; //i.e. Do not append
     142 + }else{
     143 + throw new Exception("Operation cancelled.");
     144 + }
     145 + }
     146 + }
     147 + 
     148 + //Check if header in file matches that of the columns we will be exporting.
     149 + private static boolean validHeader(File csvFile, List<LogEntryField> fields) {
     150 + BufferedReader reader;
     151 + try {
     152 + reader = new BufferedReader(new FileReader(csvFile));
     153 + } catch (FileNotFoundException e) {
     154 + return true;
     155 + }
     156 + try {
     157 + String thisHeader = buildHeader(fields);
     158 + String oldHeader = reader.readLine();
     159 + return oldHeader == null || oldHeader.equalsIgnoreCase(thisHeader);
     160 + } catch (IOException e) {
     161 + return true;
     162 + }
     163 + }
     164 + 
     165 + private static boolean shouldOverwriteExistingFilePrompt() throws Exception {
     166 + int val = JOptionPane.showConfirmDialog(null, "Replace Existing File?", "File Exists",
     167 + JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
     168 + 
     169 + if (val == JOptionPane.YES_OPTION) {
     170 + return true;
     171 + } else {
     172 + return false;
     173 + }
     174 + }
     175 + 
     176 + private static boolean promptAppendToExistingFileDialog() throws Exception {
     177 + Object[] options = {"Append",
     178 + "Overwrite", "Cancel"};
     179 + int val = JOptionPane.showOptionDialog(null,
     180 + "Append to, or overwrite the existing file?", "File Exists",
     181 + JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]);
     182 + if (val == JOptionPane.YES_OPTION) {
     183 + return true;
     184 + } else if (val == JOptionPane.NO_OPTION) {
     185 + return false;
     186 + } else {
     187 + throw new Exception("Operation cancelled.");
     188 + }
     189 + }
     190 + 
     191 + @Override
     192 + public void exportNewEntry(final LogEntry logEntry) {
     193 + if(logEntry.getStatus() == Status.PROCESSED) {
     194 + awaitingExport.add(logEntry);
     195 + }
     196 + }
     197 + 
     198 + @Override
     199 + public void exportUpdatedEntry(final LogEntry updatedEntry) {
     200 + if(updatedEntry.getStatus() == Status.PROCESSED) {
     201 + awaitingExport.add(updatedEntry);
     202 + }
     203 + }
     204 + 
     205 + public static String buildHeader(List<LogEntryField> fields) {
     206 + StringBuilder result = new StringBuilder();
     207 + 
     208 + for (int i = 0; i < fields.size(); i++) {
     209 + if(i != 0) result.append(",");
     210 + 
     211 + result.append(fields.get(i).getFullLabel());
     212 + }
     213 + 
     214 + return result.toString();
     215 + }
     216 + 
     217 + 
     218 + private static String sanitize(String string){
     219 + if(string == null) return null;
     220 + if(string.length() == 0) return "";
     221 + char first = string.toCharArray()[0];
     222 + switch (first){
     223 + case '=':
     224 + case '-':
     225 + case '+':
     226 + case '@': {
     227 + return "'" + string;
     228 + }
     229 + }
     230 + return string;
     231 + }
     232 + 
     233 + public static String entryToCSVString(LogEntry logEntry, List<LogEntryField> fields) {
     234 + StringBuilder result = new StringBuilder();
     235 + 
     236 + for (int i = 0; i < fields.size(); i++) {
     237 + if(i != 0) result.append(",");
     238 + String columnValue = String.valueOf(logEntry.getValueByKey(fields.get(i)));
     239 + result.append(StringEscapeUtils.escapeCsv(sanitize(columnValue)));
     240 + }
     241 + 
     242 + return result.toString();
     243 + }
     244 + 
     245 + public ExportController getExportController() {
     246 + return this.exportController;
     247 + }
     248 +}
     249 + 
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/exports/CSVExporterControlPanel.java
     1 +package com.nccgroup.loggerplusplus.exports;
     2 + 
     3 +import com.coreyd97.BurpExtenderUtilities.Alignment;
     4 +import com.coreyd97.BurpExtenderUtilities.PanelBuilder;
     5 +import com.nccgroup.loggerplusplus.logentry.LogEntry;
     6 +import com.nccgroup.loggerplusplus.logentry.LogEntryField;
     7 +import com.nccgroup.loggerplusplus.util.SwingWorkerWithProgressDialog;
     8 + 
     9 +import javax.swing.*;
     10 +import java.awt.*;
     11 +import java.awt.event.ActionEvent;
     12 +import java.io.File;
     13 +import java.io.FileWriter;
     14 +import java.util.List;
     15 + 
     16 +import static com.nccgroup.loggerplusplus.exports.CSVExporter.buildHeader;
     17 + 
     18 +public class CSVExporterControlPanel extends JPanel {
     19 + 
     20 + private final CSVExporter csvExporter;
     21 + 
     22 + CSVExporterControlPanel(CSVExporter csvExporter){
     23 + this.csvExporter = csvExporter;
     24 + this.setLayout(new BorderLayout());
     25 + 
     26 + JButton manualSaveButton = new JButton("Export as CSV");
     27 + manualSaveButton.addActionListener(actionEvent -> {
     28 + handleManualSave();
     29 + });
     30 + 
     31 + JToggleButton autoExportButton = new JToggleButton("Auto-export as CSV");
     32 + autoExportButton.addActionListener(new AbstractAction() {
     33 + @Override
     34 + public void actionPerformed(ActionEvent actionEvent) {
     35 + boolean newSelectedState = autoExportButton.isSelected();
     36 + if(!newSelectedState){
     37 + boolean disabled = disableExporter();
     38 + autoExportButton.setSelected(!disabled);
     39 + }else{
     40 + boolean enabled = enableExporter();
     41 + autoExportButton.setSelected(enabled);
     42 + }
     43 + }
     44 + });
     45 + 
     46 + this.add(new PanelBuilder().build(new JComponent[][]{
     47 + new JComponent[]{manualSaveButton},
     48 + new JComponent[]{autoExportButton}
     49 + }, new int[][]{
     50 + new int[]{1},
     51 + new int[]{1}
     52 + }, Alignment.FILL, 1.0, 1.0), BorderLayout.CENTER);
     53 + }
     54 + 
     55 + private boolean enableExporter(){
     56 + try {
     57 + this.csvExporter.getExportController().enableExporter(this.csvExporter);
     58 + return true;
     59 + } catch (Exception e) {
     60 + return false;
     61 + }
     62 + }
     63 + 
     64 + private boolean disableExporter(){
     65 + try{
     66 + this.csvExporter.getExportController().disableExporter(this.csvExporter);
     67 + return true;
     68 + }catch (Exception e){
     69 + return false;
     70 + }
     71 + }
     72 + 
     73 + private void handleManualSave(){
     74 + try {
     75 + List<LogEntryField> fields = csvExporter.showFieldChooserDialog();
     76 + File file = CSVExporter.getSaveFile("LoggerPlusPlus.csv");
     77 + final boolean append;
     78 + if (file.exists()) {
     79 + append = CSVExporter.shouldAppendToExistingFile(file, fields);
     80 + }else{
     81 + append = true;
     82 + }
     83 + 
     84 + final List<LogEntry> entries = this.csvExporter.getExportController().getLoggerPlusPlus().getLogEntries();
     85 + 
     86 + SwingWorkerWithProgressDialog<Void> importWorker = new SwingWorkerWithProgressDialog<Void>(JOptionPane.getFrameForComponent(this), "CSV Export", "Exporting as CSV...", entries.size()){
     87 + @Override
     88 + protected Void doInBackground() throws Exception {
     89 + super.doInBackground();
     90 + try(FileWriter fileWriter = new FileWriter(file, append)) {
     91 + if(!append) { //If we're not appending to existing file, add the header
     92 + fileWriter.append(buildHeader(fields));
     93 + fileWriter.flush();
     94 + }
     95 + 
     96 + for (int i = 0; i < entries.size(); i++) {
     97 + if(this.isCancelled()) break;
     98 + fileWriter.append("\n");
     99 + LogEntry entry = entries.get(i);
     100 + fileWriter.append(CSVExporter.entryToCSVString(entry, fields));
     101 + fileWriter.flush();
     102 + publish(i);
     103 + }
     104 + }
     105 + 
     106 + return null;
     107 + }
     108 + 
     109 + @Override
     110 + protected void done() {
     111 + super.done();
     112 + JOptionPane.showMessageDialog(CSVExporterControlPanel.this, "Export as CSV completed.", "CSV Export", JOptionPane.INFORMATION_MESSAGE);
     113 + }
     114 + };
     115 + 
     116 + importWorker.execute();
     117 + 
     118 + }catch (Exception e){
     119 + //Cancelled.
     120 + e.printStackTrace();
     121 + }
     122 + }
     123 + 
     124 +}
     125 + 
  • ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/logentry/logger/ElasticSearchLogger.java src/main/java/com/nccgroup/loggerplusplus/exports/ElasticSearchLogger.java
    1  -package com.nccgroup.loggerplusplus.logentry.logger;
     1 +package com.nccgroup.loggerplusplus.exports;
    2 2   
    3 3  import com.nccgroup.loggerplusplus.*;
    4 4  import com.nccgroup.loggerplusplus.logentry.LogEntry;
    skipped 200 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/exports/ExportController.java
     1 +package com.nccgroup.loggerplusplus.exports;
     2 + 
     3 +import com.coreyd97.BurpExtenderUtilities.Preferences;
     4 +import com.nccgroup.loggerplusplus.LoggerPlusPlus;
     5 +import com.nccgroup.loggerplusplus.logentry.LogEntry;
     6 +import com.nccgroup.loggerplusplus.preferences.PreferencesController;
     7 + 
     8 +import java.util.ArrayList;
     9 +import java.util.Collections;
     10 +import java.util.List;
     11 + 
     12 +public class ExportController {
     13 + 
     14 + private final LoggerPlusPlus loggerPlusPlus;
     15 + private final Preferences preferences;
     16 + private final List<LogExporter> exporters;
     17 + private final List<LogExporter> enabledExporters;
     18 +
     19 + public ExportController(LoggerPlusPlus loggerPlusPlus, Preferences preferences){
     20 + this.loggerPlusPlus = loggerPlusPlus;
     21 + this.preferences = preferences;
     22 + 
     23 + this.exporters = new ArrayList<>();
     24 + this.enabledExporters = Collections.synchronizedList(new ArrayList());
     25 + 
     26 + initializeExporters();
     27 + }
     28 + 
     29 + private void initializeExporters(){
     30 + this.exporters.add(new CSVExporter(this, preferences));
     31 + }
     32 + 
     33 + public List<LogExporter> getExporters() {
     34 + return exporters;
     35 + }
     36 + 
     37 + public List<LogExporter> getEnabledExporters() {
     38 + return enabledExporters;
     39 + }
     40 + 
     41 + public void enableExporter(LogExporter logExporter) throws Exception {
     42 + logExporter.setup();
     43 + this.enabledExporters.add(logExporter);
     44 + }
     45 + 
     46 + public void disableExporter(LogExporter logExporter) throws Exception {
     47 + this.enabledExporters.remove(logExporter);
     48 + logExporter.shutdown();
     49 + }
     50 + 
     51 + public void exportNewEntry(LogEntry logEntry){
     52 + for (LogExporter exporter : this.enabledExporters) {
     53 + exporter.exportNewEntry(logEntry);
     54 + }
     55 + }
     56 + 
     57 + public void exportUpdatedEntry(LogEntry logEntry){
     58 + for (LogExporter exporter : this.enabledExporters) {
     59 + exporter.exportUpdatedEntry(logEntry);
     60 + }
     61 + }
     62 + 
     63 + public LoggerPlusPlus getLoggerPlusPlus() {
     64 + return loggerPlusPlus;
     65 + }
     66 +}
     67 + 
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/exports/LogExporter.java
     1 +package com.nccgroup.loggerplusplus.exports;
     2 + 
     3 +import com.coreyd97.BurpExtenderUtilities.Preferences;
     4 +import com.nccgroup.loggerplusplus.LoggerPlusPlus;
     5 +import com.nccgroup.loggerplusplus.logentry.LogEntry;
     6 + 
     7 +import javax.swing.*;
     8 + 
     9 +public abstract class LogExporter {
     10 + 
     11 + protected final ExportController exportController;
     12 + protected final Preferences preferences;
     13 + 
     14 + protected LogExporter(ExportController exportController, Preferences preferences){
     15 + this.exportController = exportController;
     16 + this.preferences = preferences;
     17 + }
     18 + 
     19 + /**
     20 + * Configure the exporter ready for use
     21 + * @throws Exception Setup not completed
     22 + */
     23 + abstract void setup() throws Exception;
     24 + 
     25 + /**
     26 + * Handle the export of a received entry
     27 + * @param logEntry
     28 + */
     29 + abstract void exportNewEntry(LogEntry logEntry);
     30 + 
     31 + /**
     32 + * Handle the export of a received entry
     33 + * @param logEntry
     34 + */
     35 + abstract void exportUpdatedEntry(LogEntry logEntry);
     36 + 
     37 + /**
     38 + * Clean up the exporter and its resources
     39 + * @throws Exception
     40 + */
     41 + abstract void shutdown() throws Exception;
     42 + 
     43 + /**
     44 + * Build the control panel to be displayed in the preferences tab
     45 + * @return
     46 + */
     47 + public abstract JComponent getExportPanel();
     48 + 
     49 +}
     50 + 
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/imports/ImportRequestResponse.java
     1 +//
     2 +// Burp Suite Logger++
     3 +//
     4 +// Released as open source by NCC Group Plc - https://www.nccgroup.trust/
     5 +//
     6 +// Originally Developed by Soroush Dalili (@irsdl)
     7 +// Maintained by Corey Arthur (@CoreyD97)
     8 +//
     9 +// Project link: http://www.github.com/nccgroup/BurpSuiteLoggerPlusPlus
     10 +//
     11 +// Released under AGPL see LICENSE for more information
     12 +//
     13 + 
     14 +package com.nccgroup.loggerplusplus.imports;
     15 + 
     16 +import java.net.URL;
     17 + 
     18 +import com.nccgroup.loggerplusplus.LoggerPlusPlus;
     19 + 
     20 +import burp.IHttpRequestResponse;
     21 +import burp.IHttpService;
     22 + 
     23 +class ImportRequestResponse implements IHttpRequestResponse {
     24 + 
     25 + private IHttpService service;
     26 + private byte[] request;
     27 + private byte[] response;
     28 + private String comment;
     29 + private String highlight;
     30 + 
     31 + ImportRequestResponse(String url, byte[] req, byte[] res) {
     32 + LoggerHttpService srv = new LoggerHttpService(url);
     33 + setHttpService(srv);
     34 + setRequest(req);
     35 + setResponse(res);
     36 + }
     37 + 
     38 + @Override
     39 + public byte[] getRequest() {
     40 + return request;
     41 + }
     42 + 
     43 + @Override
     44 + public void setRequest(byte[] message) {
     45 + request = message;
     46 + }
     47 + 
     48 + @Override
     49 + public byte[] getResponse() {
     50 + return response;
     51 + }
     52 + 
     53 + @Override
     54 + public void setResponse(byte[] message) {
     55 + response = message;
     56 + }
     57 + 
     58 + @Override
     59 + public String getComment() {
     60 + return comment;
     61 + }
     62 + 
     63 + @Override
     64 + public void setComment(String c) {
     65 + comment = c;
     66 + }
     67 + 
     68 + @Override
     69 + public String getHighlight() {
     70 + return highlight;
     71 + }
     72 + 
     73 + @Override
     74 + public void setHighlight(String color) {
     75 + highlight = color;
     76 + }
     77 + 
     78 + @Override
     79 + public IHttpService getHttpService() {
     80 + return service;
     81 + }
     82 + 
     83 + @Override
     84 + public void setHttpService(IHttpService httpService) {
     85 + service = httpService;
     86 + }
     87 + 
     88 + private static class LoggerHttpService implements IHttpService {
     89 + 
     90 + private String host;
     91 + private int port;
     92 + private String protocol;
     93 + 
     94 + LoggerHttpService(String urlS) {
     95 + URL url;
     96 + try {
     97 + url = new URL(urlS);
     98 + } catch (Exception e) {
     99 + LoggerPlusPlus.callbacks.printError("LoggerHttpService: Error Parsing URL: " + urlS);
     100 + LoggerPlusPlus.callbacks.printError(e.toString());
     101 + return;
     102 + }
     103 + 
     104 + host = url.getHost();
     105 + protocol = url.getProtocol();
     106 + port = url.getPort();
     107 + 
     108 + if ( port < 1 ) {
     109 + switch (protocol) {
     110 + case "http":
     111 + port = 80;
     112 + break;
     113 + case "https":
     114 + port = 443;
     115 + break;
     116 + }
     117 + }
     118 + }
     119 + 
     120 + @Override
     121 + public String getHost() {
     122 + return host;
     123 + }
     124 + 
     125 + @Override
     126 + public int getPort() {
     127 + return port;
     128 + }
     129 + 
     130 + @Override
     131 + public String getProtocol() {
     132 + return protocol;
     133 + }
     134 + 
     135 + }
     136 +}
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/imports/LoggerImport.java
    skipped 66 lines
    67 67   }
    68 68   
    69 69   public static ArrayList<IHttpRequestResponse> importWStalker() {
    70  - ArrayList<String> lines = new ArrayList<String>();
    71  - ArrayList<IHttpRequestResponse> requests = new ArrayList<IHttpRequestResponse>();
     70 + ArrayList<String> lines;
     71 + ArrayList<IHttpRequestResponse> requests = new ArrayList<>();
    72 72   IExtensionHelpers helpers = LoggerPlusPlus.callbacks.getHelpers();
    73 73  
    74 74   String filename = getLoadFile();
    75 75   if ( filename.length() == 0 ) { // exit if no file selected
    76  - return new ArrayList<IHttpRequestResponse>();
     76 + return new ArrayList<>();
    77 77   }
    78 78   
    79 79   lines = readFile(filename);
    skipped 8 lines
    88 88   byte[] response = helpers.base64Decode(v[1]);
    89 89   String url = v[3];
    90 90   
    91  - LoggerRequestResponse x = new LoggerRequestResponse(url, request, response);
     91 + ImportRequestResponse x = new ImportRequestResponse(url, request, response);
    92 92   requests.add(x);
    93 93   
    94 94   } catch (Exception e) {
    skipped 48 lines
    143 143   byte[] res = helpers.stringToBytes(responseBuffer);
    144 144   
    145 145   // Add IHttpRequestResponse Object
    146  - LoggerRequestResponse x = new LoggerRequestResponse(url, req, res);
     146 + ImportRequestResponse x = new ImportRequestResponse(url, req, res);
    147 147   requests.add(x);
    148 148   
    149 149   // Reset content
    skipped 18 lines
    168 168   
    169 169   } catch (Exception e) {
    170 170   LoggerPlusPlus.callbacks.printError("importZAP: Wrong Path Format");
    171  - return new ArrayList<IHttpRequestResponse>();
     171 + return new ArrayList<>();
    172 172   }
    173 173   }
    174 174   
    skipped 36 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/imports/LoggerRequestResponse.java
    1  -//
    2  -// Burp Suite Logger++
    3  -//
    4  -// Released as open source by NCC Group Plc - https://www.nccgroup.trust/
    5  -//
    6  -// Originally Developed by Soroush Dalili (@irsdl)
    7  -// Maintained by Corey Arthur (@CoreyD97)
    8  -//
    9  -// Project link: http://www.github.com/nccgroup/BurpSuiteLoggerPlusPlus
    10  -//
    11  -// Released under AGPL see LICENSE for more information
    12  -//
    13  - 
    14  -package com.nccgroup.loggerplusplus.imports;
    15  - 
    16  -import java.net.URL;
    17  - 
    18  -import com.nccgroup.loggerplusplus.LoggerPlusPlus;
    19  - 
    20  -import burp.IHttpRequestResponse;
    21  -import burp.IHttpService;
    22  - 
    23  -class LoggerHttpService implements IHttpService {
    24  - 
    25  - private String host;
    26  - private int port;
    27  - private String protocol;
    28  - 
    29  - LoggerHttpService(String urlS) {
    30  - URL url;
    31  - try {
    32  - url = new URL(urlS);
    33  - } catch (Exception e) {
    34  - LoggerPlusPlus.callbacks.printError("LoggerHttpService: Error Parsing URL: " + urlS);
    35  - LoggerPlusPlus.callbacks.printError(e.toString());
    36  - return;
    37  - }
    38  - 
    39  - host = url.getHost();
    40  - protocol = url.getProtocol();
    41  - port = url.getPort();
    42  - 
    43  - if ( port < 1 ) {
    44  - switch (protocol) {
    45  - case "http":
    46  - port = 80;
    47  - break;
    48  - case "https":
    49  - port = 443;
    50  - break;
    51  - }
    52  - }
    53  - }
    54  - 
    55  - @Override
    56  - public String getHost() {
    57  - return host;
    58  - }
    59  - 
    60  - @Override
    61  - public int getPort() {
    62  - return port;
    63  - }
    64  - 
    65  - @Override
    66  - public String getProtocol() {
    67  - return protocol;
    68  - }
    69  - 
    70  -}
    71  - 
    72  -public class LoggerRequestResponse implements IHttpRequestResponse {
    73  - 
    74  - private IHttpService service;
    75  - private byte[] request;
    76  - private byte[] response;
    77  - private String comment;
    78  - private String highlight;
    79  - 
    80  - LoggerRequestResponse(String url, byte[] req, byte[] res) {
    81  - LoggerHttpService srv = new LoggerHttpService(url);
    82  - setHttpService(srv);
    83  - setRequest(req);
    84  - setResponse(res);
    85  - }
    86  - 
    87  - @Override
    88  - public byte[] getRequest() {
    89  - return request;
    90  - }
    91  - 
    92  - @Override
    93  - public void setRequest(byte[] message) {
    94  - request = message;
    95  - }
    96  - 
    97  - @Override
    98  - public byte[] getResponse() {
    99  - return response;
    100  - }
    101  - 
    102  - @Override
    103  - public void setResponse(byte[] message) {
    104  - response = message;
    105  - }
    106  - 
    107  - @Override
    108  - public String getComment() {
    109  - return comment;
    110  - }
    111  - 
    112  - @Override
    113  - public void setComment(String c) {
    114  - comment = c;
    115  - }
    116  - 
    117  - @Override
    118  - public String getHighlight() {
    119  - return highlight;
    120  - }
    121  - 
    122  - @Override
    123  - public void setHighlight(String color) {
    124  - highlight = color;
    125  - 
    126  - }
    127  - 
    128  - @Override
    129  - public IHttpService getHttpService() {
    130  - return service;
    131  - }
    132  - 
    133  - @Override
    134  - public void setHttpService(IHttpService httpService) {
    135  - service = httpService;
    136  - }
    137  - 
    138  -}
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/logentry/logger/FileLogger.java
    1  -package com.nccgroup.loggerplusplus.logentry.logger;
    2  - 
    3  -import burp.BurpExtender;
    4  -import burp.IHttpRequestResponse;
    5  -import com.nccgroup.loggerplusplus.*;
    6  -import com.nccgroup.loggerplusplus.logentry.LogEntry;
    7  -import com.nccgroup.loggerplusplus.logentry.LogEntryField;
    8  -import com.nccgroup.loggerplusplus.logview.logtable.LogTable;
    9  -import com.nccgroup.loggerplusplus.logview.logtable.LogTableColumn;
    10  -import com.nccgroup.loggerplusplus.logview.logtable.LogTableColumnModel;
    11  -import com.nccgroup.loggerplusplus.util.Globals;
    12  -import com.nccgroup.loggerplusplus.util.MoreHelp;
    13  -import org.apache.commons.text.StringEscapeUtils;
    14  - 
    15  -import javax.swing.*;
    16  -import javax.swing.filechooser.FileNameExtensionFilter;
    17  -import javax.swing.table.TableColumn;
    18  -import java.io.*;
    19  -import java.util.ArrayList;
    20  -import java.util.Collections;
    21  -import java.util.Enumeration;
    22  - 
    23  -/**
    24  - * Created by corey on 21/08/17.
    25  - */
    26  -public class FileLogger {
    27  - //TODO REIMPLEMENT
    28  -// private FileWriter autoSaveWriter;
    29  -// private File autoSaveFile;
    30  -// private final ExcelExporter exp;
    31  -// private boolean autoLogIncludeRequests = false;
    32  -// private boolean autoLogIncludeResponses = false;
    33  -//
    34  -// public FileLogger(){
    35  -// exp = new ExcelExporter();
    36  -// }
    37  -//
    38  -// public void saveLogs(boolean fullLogs){
    39  -// try {
    40  -// File csvFile = getSaveFile("logger++_table", false);
    41  -// if (csvFile != null) {
    42  -// exp.exportTable(csvFile, fullLogs, false, true);
    43  -// }
    44  -//
    45  -// } catch (IOException ex) {
    46  -// LoggerPlusPlus.callbacks.printError(ex.getMessage());
    47  -// }
    48  -// }
    49  -//
    50  -// public void autoLogItem(LogEntry entry, boolean includeRequests, boolean includeResponses) {
    51  -// exp.exportItem(entry, includeRequests, includeResponses);
    52  -// }
    53  -//
    54  -// // source: https://community.oracle.com/thread/1357495?start=0&tstart=0
    55  -// private File getSaveFile(String filename, boolean allowAppend) {
    56  -// File csvFile = null;
    57  -// JFileChooser chooser = null;
    58  -// FileNameExtensionFilter filter = new FileNameExtensionFilter("Excel Format (CSV)", "csv");
    59  -// chooser = new JFileChooser();
    60  -// chooser.setDialogTitle("Saving Database");
    61  -// chooser.setFileFilter(filter);
    62  -// chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
    63  -// chooser.setSelectedFile(new File(filename + ".csv"));
    64  -// chooser.setAcceptAllFileFilterUsed(false);
    65  -//
    66  -// int val = chooser.showSaveDialog(null);
    67  -//
    68  -// if (val == JFileChooser.APPROVE_OPTION) {
    69  -// csvFile = fixExtension(chooser.getSelectedFile(), "csv");
    70  -// if (csvFile == null) {
    71  -// JOptionPane.showMessageDialog(JOptionPane.getFrameForComponent(BurpExtender.instance.getUiComponent()), "File Name Specified Not Supported",
    72  -// "File Name Error", JOptionPane.ERROR_MESSAGE);
    73  -// return getSaveFile(filename, allowAppend);
    74  -// }
    75  -//
    76  -// try {
    77  -// if (csvFile.exists()) {
    78  -// if (allowAppend && validHeader(csvFile, false)) {
    79  -// csvFile = appendOrOverwrite(csvFile);
    80  -// } else {
    81  -// csvFile = checkOverwrite(csvFile);
    82  -// }
    83  -// } else {
    84  -// csvFile.createNewFile();
    85  -// }
    86  -// } catch (IOException e) {
    87  -// MoreHelp.showMessage("Could not create file. Do you have permissions for the folder?");
    88  -// return null;
    89  -// }
    90  -// return csvFile;
    91  -// }
    92  -//
    93  -// return null;
    94  -// }
    95  -//
    96  -// //Check if header in file matches that of the columns we will be exporting.
    97  -// private boolean validHeader(File csvFile, boolean isFullLog) {
    98  -// BufferedReader reader;
    99  -// try {
    100  -// reader = new BufferedReader(new FileReader(csvFile));
    101  -// } catch (FileNotFoundException e) {
    102  -// return true;
    103  -// }
    104  -// try {
    105  -// String thisHeader = getCSVHeader(LoggerPlusPlus.instance.getLogTable(), isFullLog);
    106  -// String oldHeader = reader.readLine();
    107  -// return oldHeader == null || oldHeader.equalsIgnoreCase(thisHeader);
    108  -// } catch (IOException e) {
    109  -// return true;
    110  -// }
    111  -// }
    112  -//
    113  -// private File fixExtension(File file, String prefExt) {
    114  -// String fileName = file.getName();
    115  -// String dir = file.getParentFile().getAbsolutePath();
    116  -//
    117  -// String ext = null;
    118  -//
    119  -// try {
    120  -// ext = fileName.substring(fileName.lastIndexOf("."));
    121  -// } catch (StringIndexOutOfBoundsException e) {
    122  -// ext = null;
    123  -// }
    124  -// if (ext != null && !ext.equalsIgnoreCase("." + prefExt)) {
    125  -// return file;
    126  -// }
    127  -//
    128  -// String csvName;
    129  -// if (ext == null || ext.length() == 0) {
    130  -// csvName = fileName + "." + prefExt;
    131  -// } else {
    132  -// csvName = fileName.substring(0, fileName.lastIndexOf(".") + 1) + prefExt;
    133  -// }
    134  -//
    135  -// File csvCert = new File(dir, csvName);
    136  -//
    137  -// return csvCert;
    138  -// }
    139  -//
    140  -// private File checkOverwrite(File file) throws IOException {
    141  -// int val = JOptionPane.showConfirmDialog(null, "Replace Existing File?", "File Exists",
    142  -// JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE);
    143  -//
    144  -// if (val == JOptionPane.NO_OPTION) {
    145  -// return getSaveFile(file.getName(), false);
    146  -// } else if (val == JOptionPane.CANCEL_OPTION) {
    147  -// return null;
    148  -// }
    149  -// file.delete();
    150  -// file.createNewFile();
    151  -// return file;
    152  -// }
    153  -//
    154  -// private File appendOrOverwrite(File file) throws IOException {
    155  -// Object[] options = {"Append",
    156  -// "Overwrite", "Cancel"};
    157  -// int val = JOptionPane.showOptionDialog(null,
    158  -// "Append to, or overwrite the existing file?", "File Exists",
    159  -// JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]);
    160  -// if (val == JOptionPane.YES_OPTION) {
    161  -// return file;
    162  -// } else if (val == JOptionPane.NO_OPTION) {
    163  -// file.delete();
    164  -// file.createNewFile();
    165  -// return file;
    166  -// } else {
    167  -// return null;
    168  -// }
    169  -// }
    170  -//
    171  -//
    172  -// public void setAutoSave(boolean enabled) {
    173  -// if (enabled) {
    174  -// autoSaveFile = getSaveFile("logger++_auto", true);
    175  -// if (autoSaveFile != null) {
    176  -// LoggerPlusPlus.preferences.setSetting(Globals.PREF_AUTO_SAVE, true);
    177  -// try {
    178  -// autoSaveWriter = new FileWriter(autoSaveFile, true);
    179  -// int result = JOptionPane.showConfirmDialog(null, "Include REQUEST bodies in the logs?","Automatic Logging", JOptionPane.YES_OPTION);
    180  -// autoLogIncludeRequests = result == JOptionPane.YES_OPTION;
    181  -//
    182  -// result = JOptionPane.showConfirmDialog(null, "Include RESPONSE bodies in the logs?","Automatic Logging", JOptionPane.YES_OPTION);
    183  -// autoLogIncludeResponses = result == JOptionPane.YES_OPTION;
    184  -// if (autoSaveFile.length() == 0)
    185  -// exp.addHeader(autoSaveWriter, autoLogIncludeRequests, autoLogIncludeResponses);
    186  -//
    187  -// LoggerPlusPlus.instance.getLogProcessor().addLogListener(this);
    188  -//
    189  -// } catch (IOException e) {
    190  -// autoSaveFile = null;
    191  -// enabled = false;
    192  -// }
    193  -// } else {
    194  -// enabled = false;
    195  -// }
    196  -// } else {
    197  -// autoSaveFile = null;
    198  -// try{
    199  -// autoSaveWriter.close();
    200  -// } catch (Exception e) {}
    201  -// autoSaveWriter = null;
    202  -// LoggerPlusPlus.instance.getLogProcessor().removeLogListener(this);
    203  -// }
    204  -// LoggerPlusPlus.preferences.setSetting(Globals.PREF_AUTO_SAVE, enabled);
    205  -// LoggerPlusPlus.instance.getLoggerOptionsPanel().setAutoSaveBtn(enabled);
    206  -// }
    207  -//
    208  -// @Override
    209  -// public void onRequestAdded(int modelIndex, final LogEntry logEntry, boolean hasResponse) {
    210  -// if(!hasResponse) return;
    211  -// Thread saveThread = new Thread(){
    212  -// @Override
    213  -// public void run() {
    214  -// synchronized (autoSaveWriter){
    215  -// autoLogItem(logEntry, autoLogIncludeRequests, autoLogIncludeResponses);
    216  -// }
    217  -// }
    218  -// };
    219  -// saveThread.start();
    220  -// }
    221  -//
    222  -// @Override
    223  -// public void onResponseUpdated(int modelRow, final LogEntry existingEntry) {
    224  -// Thread saveThread = new Thread(){
    225  -// @Override
    226  -// public void run() {
    227  -// synchronized (autoSaveWriter){
    228  -// autoLogItem(existingEntry, autoLogIncludeRequests, autoLogIncludeResponses);
    229  -// }
    230  -// }
    231  -// };
    232  -// saveThread.start();
    233  -// }
    234  -//
    235  -// @Override
    236  -// public void onRequestRemoved(int modelIndex, LogEntry logEntry) {
    237  -//
    238  -// }
    239  -//
    240  -// @Override
    241  -// public void onLogsCleared() {
    242  -//
    243  -// }
    244  -//
    245  -// // source: http://book.javanb.com/swing-hacks/swinghacks-chp-3-sect-6.html
    246  -// public class ExcelExporter {
    247  -//
    248  -// public void addHeader(FileWriter writer, boolean isFullLog) throws IOException {
    249  -// writer.write(getCSVHeader(LoggerPlusPlus.instance.getLogTable(), isFullLog) + "\n");
    250  -// }
    251  -//
    252  -// public void addHeader(FileWriter writer, boolean includeRequest, boolean includeResponse) throws IOException {
    253  -// writer.write(getCSVHeader(LoggerPlusPlus.instance.getLogTable(), includeRequest, includeResponse) + "\n");
    254  -// }
    255  -//
    256  -// public void exportTable(File file, boolean isFullLog, boolean append, boolean header) throws IOException {
    257  -// FileWriter out = new FileWriter(file, append);
    258  -//
    259  -// if (header) {
    260  -// out.write(getCSVHeader(LoggerPlusPlus.instance.getLogTable(), isFullLog));
    261  -// out.write("\n");
    262  -// }
    263  -//
    264  -// for (LogEntry item : LoggerPlusPlus.instance.getLogProcessor().getLogEntries()) {
    265  -// out.write(entryToCSVString(item, isFullLog) + "\n");
    266  -// }
    267  -//
    268  -// out.close();
    269  -// MoreHelp.showMessage("Log saved to " + file.getAbsolutePath());
    270  -// }
    271  -//
    272  -// public void exportItem(LogEntry logEntry, boolean includeRequests, boolean includeResponses) {
    273  -// if(autoSaveWriter != null) {
    274  -// try {
    275  -// autoSaveWriter.write(entryToCSVString(logEntry, includeRequests, includeResponses));
    276  -// autoSaveWriter.write("\n");
    277  -// autoSaveWriter.flush();
    278  -// } catch (Exception e) {
    279  -// MoreHelp.showMessage("Could not save log. Automatic logging will be disabled.");
    280  -// setAutoSave(false);
    281  -// }
    282  -// }else{
    283  -// MoreHelp.showMessage("Could not save log. Automatic logging will be disabled.");
    284  -// setAutoSave(false);
    285  -// }
    286  -// }
    287  -//
    288  -// }
    289  -//
    290  -// public static String getCSVHeader(LogTable table, boolean isFullLog) {
    291  -// return getCSVHeader(table, isFullLog, isFullLog);
    292  -// }
    293  -//
    294  -// public static String getCSVHeader(LogTable table, boolean includeRequest, boolean includeResponse) {
    295  -// StringBuilder result = new StringBuilder();
    296  -//
    297  -// boolean firstDone = false;
    298  -// ArrayList<LogTableColumn> columns = new ArrayList<>();
    299  -// Enumeration<TableColumn> columnEnumeration = table.getColumnModel().getColumns();
    300  -// while(columnEnumeration.hasMoreElements()){
    301  -// columns.add((LogTableColumn) columnEnumeration.nextElement());
    302  -// }
    303  -//
    304  -// columns.remove(table.getColumnModel().getColumnByIdentifier(LogEntryField.NUMBER));
    305  -//
    306  -// Collections.sort(columns);
    307  -// for (LogTableColumn logTableColumn : columns) {
    308  -// if(logTableColumn.isVisible()) {
    309  -// if(firstDone) {
    310  -// result.append(",");
    311  -// }else{
    312  -// firstDone = true;
    313  -// }
    314  -// result.append(logTableColumn.getName());
    315  -// }
    316  -// }
    317  -//
    318  -// if(includeRequest) {
    319  -// result.append(",");
    320  -// result.append("Request");
    321  -// }
    322  -// if(includeResponse) {
    323  -// result.append(",");
    324  -// result.append("Response");
    325  -// }
    326  -// return result.toString();
    327  -// }
    328  -//
    329  -//
    330  -// public String entryToCSVString(LogEntry logEntry, boolean isFullLog) {
    331  -// return entryToCSVString(logEntry, isFullLog, isFullLog);
    332  -// }
    333  -//
    334  -// private String sanitize(String string){
    335  -// if(string == null) return null;
    336  -// if(string.length() == 0) return "";
    337  -// char first = string.toCharArray()[0];
    338  -// switch (first){
    339  -// case '=':
    340  -// case '-':
    341  -// case '+':
    342  -// case '@': {
    343  -// return "'" + string;
    344  -// }
    345  -// }
    346  -// return string;
    347  -// }
    348  -//
    349  -// public String entryToCSVString(LogEntry logEntry, boolean includeRequests, boolean includeResponses) {
    350  -// StringBuilder result = new StringBuilder();
    351  -//
    352  -// LogTableColumnModel columnModel = LoggerPlusPlus.instance.getLogTable().getColumnModel();
    353  -// ArrayList<LogTableColumn> columns = new ArrayList<>();
    354  -// Enumeration<TableColumn> columnEnumeration = columnModel.getColumns();
    355  -// while(columnEnumeration.hasMoreElements()){
    356  -// columns.add((LogTableColumn) columnEnumeration.nextElement());
    357  -// }
    358  -//
    359  -// columns.remove(columnModel.getColumnByIdentifier(LogEntryField.NUMBER));
    360  -//
    361  -// Collections.sort(columns);
    362  -// boolean firstDone = false;
    363  -// for (LogTableColumn logTableColumn : columns) {
    364  -// if(logTableColumn.isVisible() && logTableColumn.getIdentifier() != LogEntryField.NUMBER){
    365  -// if(firstDone){
    366  -// result.append(",");
    367  -// }else{
    368  -// firstDone = true;
    369  -// }
    370  -// String columnValue = String.valueOf(logEntry.getValueByKey(logTableColumn.getIdentifier()));
    371  -//
    372  -// result.append(StringEscapeUtils.escapeCsv(sanitize(columnValue)));
    373  -// }
    374  -// }
    375  -//
    376  -// IHttpRequestResponse requestResponse = logEntry.getRequestResponse();
    377  -// if(includeRequests) {
    378  -//
    379  -// result.append(",");
    380  -// if (requestResponse != null && requestResponse.getRequest() != null)
    381  -// result.append(StringEscapeUtils.escapeCsv(sanitize(new String(requestResponse.getRequest()))));
    382  -// }
    383  -// if(includeResponses) {
    384  -// result.append(",");
    385  -// if(requestResponse != null && requestResponse.getResponse() != null)
    386  -// result.append(StringEscapeUtils.escapeCsv(sanitize(new String(requestResponse.getResponse()))));
    387  -// }
    388  -// return result.toString();
    389  -// }
    390  - 
    391  -}
    392  - 
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/logview/logtable/LogTable.java
    skipped 216 lines
    217 217   ((JScrollPane) this.getParent().getParent()).getVerticalScrollBar().setValue(0);
    218 218   }
    219 219   
    220  - // to saveFilters the new grepTable changes
    221  - public void saveTableChanges(){
    222  - // saveFilters it to the relevant variables and preferences
    223  - this.getColumnModel().saveLayout();
    224  - }
    225  - 
    226 220   @Override
    227 221   public LogTableModel getModel(){
    228 222   return (LogTableModel) super.getModel();
    skipped 5 lines
  • ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/logview/logtable/LogTableColumnModel.java
    skipped 157 lines
    158 158   //Remove the column from the view and adjust others to fit.
    159 159   removeColumn(logTableColumn);
    160 160   }
     161 + saveLayout();
    161 162   }
    162 163   
    163 164   public Enumeration<LogTableColumn> getAllColumns() {
    skipped 4 lines
  • ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/logview/logtable/TableHeaderMenu.java
    skipped 93 lines
    94 94   // Save it only if it is different! no need to refresh the columns
    95 95   if(!newValue.equals(columnObj.getDefaultVisibleName())){
    96 96   columnObj.setVisibleName(newValue);
    97  - saveAndReloadTableSettings();
     97 + logTableController.getLogTableColumnModel().saveLayout();
    98 98   }
    99 99   }
    100 100   });
    skipped 3 lines
    104 104   item.addActionListener(new ActionListener() {
    105 105   public void actionPerformed(ActionEvent e) {
    106 106   logTable.getColumnModel().toggleHidden(columnObj);
    107  - saveAndReloadTableSettings();
    108 107   }
    109 108   });
    110 109   menu.add(item);
    skipped 29 lines
    140 139   logTable.getColumnModel().toggleHidden(logTableColumn);
    141 140   }
    142 141   }
    143  - saveAndReloadTableSettings();
     142 + logTableController.getLogTableColumnModel().saveLayout();
    144 143   }
    145 144   });
    146 145   subMenuVisibleCols.add(item);
    skipped 6 lines
    153 152   visibleItem.addActionListener(new ActionListener() {
    154 153   public void actionPerformed(ActionEvent e) {
    155 154   logTable.getColumnModel().toggleHidden(logTableColumn);
    156  - saveAndReloadTableSettings();
    157 155   }
    158 156   });
    159 157   subMenuVisibleCols.add(visibleItem);
    skipped 2 lines
    162 160   menu.add(subMenuVisibleCols);
    163 161   
    164 162   menu.show(e.getComponent(), e.getX(), e.getY());
    165  - }
    166  - 
    167  - public void saveAndReloadTableSettings(){
    168  - //Stop automatically logging, prevents changing of csv format midway through
    169  - //TODO constant csv format?
    170  - if(logTableController.getPreferences().getSetting(Globals.PREF_AUTO_SAVE)){
    171  - logTableController.getPreferences().setSetting(Globals.PREF_AUTO_SAVE, false);
    172  -// logTableController.getFileLogger().setAutoSave(false); //TODO FIXME
    173  - MoreHelp.showMessage("The logTable structure has been changed. Autosave was disabled to prevent invalid csv.");
    174  - }
    175  - logTable.saveTableChanges();
    176  -// logTable.getModel().fireTableStructureChanged();
    177 163   }
    178 164   
    179 165   
    skipped 5 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/logview/processor/LogProcessor.java
    skipped 2 lines
    3 3  import burp.*;
    4 4  import com.coreyd97.BurpExtenderUtilities.Preferences;
    5 5  import com.nccgroup.loggerplusplus.LoggerPlusPlus;
     6 +import com.nccgroup.loggerplusplus.exports.ExportController;
    6 7  import com.nccgroup.loggerplusplus.filter.colorfilter.ColorFilter;
    7 8  import com.nccgroup.loggerplusplus.logentry.LogEntry;
    8  -import com.nccgroup.loggerplusplus.logentry.LogManagerHelper;
    9 9  import com.nccgroup.loggerplusplus.logentry.Status;
    10 10  import com.nccgroup.loggerplusplus.logview.logtable.LogTableController;
    11 11  import com.nccgroup.loggerplusplus.util.NamedThreadFactory;
    skipped 15 lines
    27 27   
    28 28   private final LoggerPlusPlus loggerPlusPlus;
    29 29   private final LogTableController logTableController;
     30 + private final ExportController exportController;
    30 31   private final Preferences preferences;
    31 32   private final ConcurrentHashMap<Integer, UUID> proxyIdToUUIDMap;
    32 33   private final ConcurrentHashMap<UUID, LogEntry> entriesPendingProcessing;
    skipped 9 lines
    42 43   * TODO SQLite integration
    43 44   * TODO Capture requests modified after logging using request obtained from response objects.
    44 45   */
    45  - public LogProcessor(LoggerPlusPlus loggerPlusPlus, LogTableController logTableController){
     46 + public LogProcessor(LoggerPlusPlus loggerPlusPlus, LogTableController logTableController, ExportController exportController){
    46 47   this.loggerPlusPlus = loggerPlusPlus;
    47 48   this.logTableController = logTableController;
     49 + this.exportController = exportController;
    48 50   this.preferences = this.loggerPlusPlus.getPreferencesController().getPreferences();
    49 51   
    50 52   this.proxyIdToUUIDMap = new ConcurrentHashMap<>();
    skipped 37 lines
    88 90   if(isRequestOnly){
    89 91   final LogEntry logEntry = new LogEntry(toolFlag, arrivalTime, httpMessage);
    90 92   //Tag the request with the UUID in the comment field, as this persists for when we get the response back!
    91  - LogManagerHelper.tagRequestResponseWithUUID(instanceIdentifier, logEntry.getIdentifier(), httpMessage);
     93 + LogProcessorHelper.tagRequestResponseWithUUID(instanceIdentifier, logEntry.getIdentifier(), httpMessage);
    92 94   submitNewEntryProcessingRunnable(logEntry);
    93 95   }else{
    94  - UUID uuid = LogManagerHelper.extractAndRemoveUUIDFromRequestResponseComment(instanceIdentifier, httpMessage);
     96 + UUID uuid = LogProcessorHelper.extractAndRemoveUUIDFromRequestResponseComment(instanceIdentifier, httpMessage);
    95 97   if(uuid != null) {
    96 98   updateRequestWithResponse(uuid, arrivalTime, httpMessage);
    97 99   }
    skipped 182 lines
    280 282   }
    281 283   
    282 284   void addProcessedEntry(LogEntry logEntry){
     285 + exportController.exportNewEntry(logEntry);
    283 286   SwingUtilities.invokeLater(() -> {
    284 287   logTableController.getLogTableModel().addEntry(logEntry);
    285 288   });
    286 289   }
    287 290   
    288 291   void updateExistingEntry(LogEntry logEntry){
     292 + exportController.exportUpdatedEntry(logEntry);
    289 293   SwingUtilities.invokeLater(() -> {
    290 294   logTableController.getLogTableModel().updateEntry(logEntry);
    291 295   });
    skipped 39 lines
    331 335   long responseTimeout = 1000 * ((Integer) preferences.getSetting(PREF_RESPONSE_TIMEOUT)).longValue();
    332 336   if (timeNow - entryTime > responseTimeout) {
    333 337   iter.remove();
    334  - LogManagerHelper.extractAndRemoveUUIDFromRequestResponseComment(instanceIdentifier, logEntry.requestResponse);
     338 + LogProcessorHelper.extractAndRemoveUUIDFromRequestResponseComment(instanceIdentifier, logEntry.requestResponse);
    335 339   logEntry.requestResponse.setComment("Timed Out " + logEntry.requestResponse.getComment());
    336 340   removedUUIDs.add(abandonedEntry.getKey());
    337 341   }
    skipped 24 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/logentry/LogManagerHelper.java src/main/java/com/nccgroup/loggerplusplus/logview/processor/LogProcessorHelper.java
    1  -package com.nccgroup.loggerplusplus.logentry;
     1 +package com.nccgroup.loggerplusplus.logview.processor;
    2 2   
    3 3  import burp.IHttpRequestResponse;
    4 4  import com.nccgroup.loggerplusplus.util.Globals;
    skipped 1 lines
    6 6  import java.util.UUID;
    7 7  import java.util.regex.Matcher;
    8 8   
    9  -public class LogManagerHelper {
     9 +public class LogProcessorHelper {
    10 10   
    11 11   public static void tagRequestResponseWithUUID(String instanceIdentifier, UUID uuid, IHttpRequestResponse requestResponse){
    12 12   String originalComment = requestResponse.getComment() != null ? requestResponse.getComment() : "";
    skipped 17 lines
  • ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/preferences/LoggerPreferenceFactory.java
    skipped 5 lines
    6 6  import com.coreyd97.BurpExtenderUtilities.PreferenceFactory;
    7 7  import com.coreyd97.BurpExtenderUtilities.Preferences;
    8 8  import com.google.gson.reflect.TypeToken;
     9 +import com.nccgroup.loggerplusplus.logentry.LogEntryField;
    9 10  import com.nccgroup.loggerplusplus.logview.logtable.LogTableColumn;
    10 11  import com.nccgroup.loggerplusplus.filter.colorfilter.ColorFilter;
    11 12  import com.nccgroup.loggerplusplus.filter.logfilter.LogFilter;
    skipped 9 lines
    21 22   
    22 23   private HashMap<UUID, ColorFilter> defaultColorFilters;
    23 24   private ArrayList<LogTableColumn> defaultlogTableColumns;
     25 + private List<LogEntryField> defaultExportFields;
    24 26   
    25 27   public LoggerPreferenceFactory(IGsonProvider gsonProvider, ILogProvider logProvider, IBurpExtenderCallbacks callbacks){
    26 28   super("LoggerPlusPlus", gsonProvider, logProvider, callbacks);
    skipped 9 lines
    36 38   Globals.DEFAULT_COLOR_FILTERS_JSON, new TypeToken<HashMap<UUID, ColorFilter>>(){}.getType());
    37 39   defaultlogTableColumns = this.gsonProvider.getGson().fromJson(
    38 40   Globals.DEFAULT_LOG_TABLE_COLUMNS_JSON, new TypeToken<List<LogTableColumn>>() {}.getType());
     41 + defaultExportFields = this.gsonProvider.getGson().fromJson(
     42 + Globals.DEFAULT_EXPORT_FIELDS, new TypeToken<List<LogEntryField>>(){}.getType());
    39 43   }
    40 44   
    41 45   @Override
    skipped 34 lines
    76 80   prefs.registerSetting(PREF_ELASTIC_INDEX, String.class, "logger", Preferences.Visibility.GLOBAL);
    77 81   prefs.registerSetting(PREF_ELASTIC_DELAY, Integer.class, 120, Preferences.Visibility.GLOBAL);
    78 82   prefs.registerSetting(PREF_ELASTIC_INCLUDE_REQ_RESP, Boolean.class, false, Preferences.Visibility.GLOBAL);
     83 + prefs.registerSetting(PREF_PREVIOUS_CSV_FIELDS, new TypeToken<List<LogEntryField>>(){}.getType(), Preferences.Visibility.GLOBAL);
    79 84   
    80 85   prefs.registerSetting(PREF_AUTO_SAVE, Boolean.class, false, Preferences.Visibility.VOLATILE);
    81 86   prefs.registerSetting(PREF_AUTO_SCROLL, Boolean.class, true, Preferences.Visibility.VOLATILE);
    skipped 4 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/preferences/PreferencesController.java
    skipped 13 lines
    14 14   private final IGsonProvider gsonProvider;
    15 15   private final Preferences preferences;
    16 16   
    17  - private final PreferencesPanel preferencesPanel;
     17 + private PreferencesPanel preferencesPanel;
    18 18   
    19 19   public PreferencesController(LoggerPlusPlus loggerPlusPlus, LoggingController loggingController) {
    20 20   this.loggerPlusPlus = loggerPlusPlus;
    skipped 15 lines
    36 36   //Reset preferences which may cause issues.
    37 37   preferences.resetSettings(new HashSet<>(Arrays.asList(Globals.VERSION_CHANGE_SETTINGS_TO_RESET)));
    38 38   }
    39  - 
    40  - this.preferencesPanel = new PreferencesPanel(this);
    41 39   }
    42 40   
    43 41   public PreferencesPanel getPreferencesPanel() {
     42 + if(preferencesPanel == null) {
     43 + preferencesPanel = new PreferencesPanel(this);
     44 + }
    44 45   return preferencesPanel;
    45 46   }
    46 47   
    skipped 13 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/preferences/PreferencesPanel.java
    skipped 21 lines
    22 22  import com.nccgroup.loggerplusplus.filter.colorfilter.ColorFilter;
    23 23  import com.nccgroup.loggerplusplus.filter.savedfilter.SavedFilter;
    24 24  import com.nccgroup.loggerplusplus.imports.LoggerImport;
    25  -import com.nccgroup.loggerplusplus.logentry.logger.FileLogger;
    26  -import com.nccgroup.loggerplusplus.util.Globals;
    27 25  import com.nccgroup.loggerplusplus.util.MoreHelp;
    28 26   
    29 27  import javax.swing.*;
    skipped 14 lines
    44 42   private JToggleButton btnAutoSaveLogs;
    45 43   private final JToggleButton esEnabled;
    46 44   private final JLabel esValueChangeWarning = new JLabel("Warning: Changing preferences while running will disable the upload service and clear all pending groups.");
    47  - private final FileLogger fileLogger;
    48 45   
    49 46   
    50 47   /**
    skipped 4 lines
    55 52   this.preferences = preferencesController.getPreferences();
    56 53   
    57 54   PanelBuilder panelBuilder = new PanelBuilder(this.preferences);
    58  - this.fileLogger = new FileLogger();
    59 55   this.esValueChangeWarning.setForeground(Color.RED);
    60 56   
    61 57   ComponentGroup statusPanel = panelBuilder.createComponentGroup("Status");
    skipped 78 lines
    140 136   }).setEnabled(true);
    141 137   
    142 138   ComponentGroup exportGroup = panelBuilder.createComponentGroup("Export");
    143  - exportGroup.addButton("Save log table as CSV", actionEvent -> {
    144  -// fileLogger.saveLogs(false);
    145  - });
    146  - exportGroup.addButton("Save full logs as CSV (slow)", actionEvent -> {
    147  -// fileLogger.saveLogs(true);
    148  - });
    149  - btnAutoSaveLogs = exportGroup.addToggleButton("Autosave as CSV", actionEvent -> {
    150  -// fileLogger.setAutoSave(!(boolean) preferences.getSetting(PREF_AUTO_SAVE));
     139 + preferencesController.getLoggerPlusPlus().getExportController().getExporters().forEach(logExporter -> {
     140 + exportGroup.addComponent(logExporter.getExportPanel());
    151 141   });
     142 + 
     143 +// exportGroup.addButton("Save log table as CSV", actionEvent -> {
     144 +//// fileLogger.saveLogs(false);
     145 +// });
     146 +// exportGroup.addButton("Save full logs as CSV (slow)", actionEvent -> {
     147 +//// fileLogger.saveLogs(true);
     148 +// });
     149 +// btnAutoSaveLogs = exportGroup.addToggleButton("Autosave as CSV", actionEvent -> {
     150 +//// fileLogger.setAutoSave(!(boolean) preferences.getSetting(PREF_AUTO_SAVE));
     151 +// });
    152 152   
    153 153   ComponentGroup elasticPanel = panelBuilder.createComponentGroup("Elastic Search");
    154 154   esEnabled = elasticPanel.addToggleButton("Disabled", actionEvent -> {
    skipped 146 lines
    301 301   }
    302 302   }
    303 303   }).start();
    304  - }
    305  - 
    306  - public FileLogger getFileLogger() {
    307  - return fileLogger;
    308 304   }
    309 305  }
    310 306   
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/util/FieldSelectorDialog.java
     1 +package com.nccgroup.loggerplusplus.util;
     2 + 
     3 +import com.coreyd97.BurpExtenderUtilities.Alignment;
     4 +import com.coreyd97.BurpExtenderUtilities.PanelBuilder;
     5 +import com.google.gson.internal.LinkedTreeMap;
     6 +import com.nccgroup.loggerplusplus.logentry.LogEntryField;
     7 +import com.nccgroup.loggerplusplus.util.userinterface.renderer.BooleanRenderer;
     8 + 
     9 +import javax.swing.*;
     10 +import javax.swing.table.AbstractTableModel;
     11 +import java.awt.*;
     12 +import java.util.*;
     13 +import java.util.List;
     14 + 
     15 +public class FieldSelectorDialog extends JDialog {
     16 + 
     17 + private List<LogEntryField> fieldList;
     18 + private LinkedTreeMap<LogEntryField, Boolean> selectedFields;
     19 + 
     20 + public FieldSelectorDialog(Frame owner, String title, List<LogEntryField> defaults){
     21 + super(owner, title, true);
     22 + this.setLayout(new BorderLayout());
     23 + fieldList = new ArrayList<>();
     24 + selectedFields = new LinkedTreeMap<>();
     25 + if(defaults == null) defaults = Collections.EMPTY_LIST;
     26 + for (LogEntryField field : LogEntryField.values()) {
     27 + if(field == LogEntryField.NUMBER) continue;
     28 + fieldList.add(field);
     29 + selectedFields.put(field, defaults.contains(field));
     30 + }
     31 + 
     32 + buildDialog();
     33 + }
     34 + 
     35 + private void buildDialog(){
     36 + 
     37 + JLabel message = new JLabel("Select fields to be exported:");
     38 + JTable fieldTable = new JTable(new TableModel());
     39 + fieldTable.setDefaultRenderer(Boolean.class, new BooleanRenderer());
     40 + JScrollPane fieldScrollPane = new JScrollPane(fieldTable);
     41 + JButton okButton = new JButton("OK");
     42 + okButton.addActionListener(actionEvent -> {
     43 + this.dispose();
     44 + });
     45 + JButton cancelButton = new JButton("Cancel");
     46 + cancelButton.addActionListener(actionEvent -> {
     47 + selectedFields.clear();
     48 + this.dispose();
     49 + });
     50 + 
     51 + JPanel panel = new PanelBuilder().build(
     52 + new JComponent[][]{
     53 + new JComponent[]{message, message, message},
     54 + new JComponent[]{fieldScrollPane, fieldScrollPane, fieldScrollPane},
     55 + new JComponent[]{null, okButton, cancelButton}
     56 + }, new int[][]{
     57 + new int[]{1, 1, 1},
     58 + new int[]{0, 0, 0},
     59 + new int[]{0, 0, 0},
     60 + }, Alignment.FILL, 1.0, 1.0);
     61 + this.add(panel, BorderLayout.CENTER);
     62 + this.pack();
     63 + }
     64 + 
     65 + private class TableModel extends AbstractTableModel {
     66 + 
     67 + @Override
     68 + public int getRowCount() {
     69 + return selectedFields.size();
     70 + }
     71 + 
     72 + @Override
     73 + public int getColumnCount() {
     74 + return 2;
     75 + }
     76 + 
     77 + @Override
     78 + public Class<?> getColumnClass(int columnIndex) {
     79 + return columnIndex == 0 ? String.class : Boolean.class;
     80 + }
     81 + 
     82 + @Override
     83 + public String getColumnName(int column) {
     84 + return column == 0 ? "Field" : "Enabled";
     85 + }
     86 + 
     87 + @Override
     88 + public boolean isCellEditable(int rowIndex, int columnIndex) {
     89 + return columnIndex == 1;
     90 + }
     91 + 
     92 + @Override
     93 + public void setValueAt(Object value, int rowIndex, int columnIndex) {
     94 + LogEntryField field = fieldList.get(rowIndex);
     95 + selectedFields.put(field, (Boolean) value);
     96 + }
     97 + 
     98 + @Override
     99 + public Object getValueAt(int row, int col) {
     100 + if(col == 0){
     101 + return fieldList.get(row);
     102 + }else{
     103 + return selectedFields.get(fieldList.get(row));
     104 + }
     105 + }
     106 + }
     107 + 
     108 + public List<LogEntryField> getSelectedFields() {
     109 + List<LogEntryField> selectedList = new ArrayList<>();
     110 + selectedFields.forEach((field, selected) -> {
     111 + if(selected) selectedList.add(field);
     112 + });
     113 + 
     114 + return selectedList;
     115 + }
     116 +}
     117 + 
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/util/Globals.java
    skipped 50 lines
    51 51   public static final String PREF_AUTO_SAVE = "autoSave";
    52 52   public static final String PREF_AUTO_SCROLL = "autoScroll";
    53 53   public static final String PREF_GREP_HISTORY = "grepHistory";
     54 + public static final String PREF_PREVIOUS_CSV_FIELDS = "previousCSVFields";
    54 55   
    55 56   public static final String[] VERSION_CHANGE_SETTINGS_TO_RESET = new String[]{
    56 57   PREF_LOG_TABLE_SETTINGS
    skipped 2 lines
    59 60   public static final String DEFAULT_COLOR_FILTERS_JSON = "{\"2add8ace-b652-416a-af08-4d78c5d22bc7\":{\"uid\":\"2add8ace-b652-416a-af08-4d78c5d22bc7\"," +
    60 61   "\"filter\":{\"filter\":\"Request.Complete == False\"},\"filterString\":\"Request.Complete == False\",\"backgroundColor\":{\"value\":-16777216,\"falpha\":0.0}," +
    61 62   "\"foregroundColor\":{\"value\":-65536,\"falpha\":0.0},\"enabled\":true,\"modified\":false,\"shouldRetest\":true,\"priority\":1}}";
     63 + public static final String DEFAULT_EXPORT_FIELDS = "[]";
     64 + 
    62 65   private static int colModelIndex = 0;
    63 66   private static int colOrder = 0;
    64 67   public static final String DEFAULT_LOG_TABLE_COLUMNS_JSON = new StringBuilder().append("[")
    skipped 58 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/util/SwingWorkerWithProgressDialog.java
     1 +package com.nccgroup.loggerplusplus.util;
     2 + 
     3 +import com.coreyd97.BurpExtenderUtilities.Alignment;
     4 +import com.coreyd97.BurpExtenderUtilities.PanelBuilder;
     5 + 
     6 +import javax.swing.*;
     7 +import java.awt.*;
     8 +import java.awt.event.ActionEvent;
     9 +import java.util.Collections;
     10 +import java.util.List;
     11 + 
     12 +public abstract class SwingWorkerWithProgressDialog<T> extends SwingWorker<T, Integer> {
     13 + 
     14 + private final JProgressBar jProgressBar;
     15 + private final JDialog dialog;
     16 + 
     17 + public SwingWorkerWithProgressDialog(Frame dialogOwner, String title, String message, int progressBarMax){
     18 + jProgressBar = new JProgressBar(0, progressBarMax);
     19 + dialog = new JDialog(dialogOwner, title, false);
     20 + JLabel messageLabel = new JLabel(message);
     21 + JButton cancelButton = new JButton(new AbstractAction("Cancel") {
     22 + @Override
     23 + public void actionPerformed(ActionEvent actionEvent) {
     24 + SwingWorkerWithProgressDialog.this.cancel(true);
     25 + }
     26 + });
     27 + 
     28 + JPanel bodyPanel = new PanelBuilder().build(new Component[][]{
     29 + new Component[]{messageLabel, messageLabel},
     30 + new Component[]{jProgressBar, cancelButton}
     31 + }, new int[][]{
     32 + new int[]{0, 0},
     33 + new int[]{1, 0}
     34 + }, Alignment.CENTER, 0.8, 0.8);
     35 + 
     36 + dialog.add(bodyPanel);
     37 + dialog.setResizable(false);
     38 + dialog.pack();
     39 + 
     40 + dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
     41 + }
     42 + 
     43 + @Override
     44 + protected T doInBackground() throws Exception {
     45 + dialog.setVisible(true);
     46 + return null;
     47 + }
     48 + 
     49 + @Override
     50 + protected void process(List<Integer> chunks) {
     51 + jProgressBar.setValue(Collections.max(chunks));
     52 + }
     53 + 
     54 + @Override
     55 + protected void done() {
     56 + dialog.dispose();
     57 + super.done();
     58 + }
     59 +}
     60 + 
Please wait...
Page is in error, reload to recover