Projects STRLCPY LoggerPlusPlus Commits cb3e1968
🤬
  • ■ ■ ■ ■ ■ ■
    build.gradle
    skipped 13 lines
    14 14  }
    15 15   
    16 16  dependencies {
    17  - compileOnly 'net.portswigger.burp.extender:burp-extender-api:2.3'
    18  -// compileOnly 'net.portswigger.burp.extender:montoya-api:0.9.5'
    19  - compileOnly 'org.projectlombok:lombok:1.18.24'
    20  - annotationProcessor 'org.projectlombok:lombok:1.18.24'
    21  - 
     17 + implementation 'net.portswigger.burp.extensions:montoya-api:1.0.0'
    22 18   implementation 'org.swinglabs:swingx:1.6.1'
    23  - implementation 'com.github.CoreyD97:BurpExtenderUtilities:e800fd2d'
    24  - implementation 'com.google.code.gson:gson:2.10'
    25  - implementation 'org.elasticsearch.client:elasticsearch-rest-high-level-client:7.5.2'
     19 + implementation 'com.github.CoreyD97:Burp-Montoya-Utilities:07e3e02b'
     20 + implementation 'org.elasticsearch.client:elasticsearch-rest-high-level-client:7.15.2'
    26 21   implementation 'org.apache.httpcomponents:httpclient:4.5.13'
    27 22   implementation 'org.apache.commons:commons-text:1.10.0'
    28 23   implementation 'org.apache.logging.log4j:log4j-core:2.19.0'
    skipped 21 lines
  • ■ ■ ■ ■
    gradle/wrapper/gradle-wrapper.properties
    1 1  distributionBase=GRADLE_USER_HOME
    2 2  distributionPath=wrapper/dists
    3  -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
     3 +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
    4 4  zipStoreBase=GRADLE_USER_HOME
    5 5  zipStorePath=wrapper/dists
    6 6   
  • ■ ■ ■ ■ ■ ■
    src/main/java/burp/BurpExtender.java
    1  -//
    2  -// Burp Suite Logger++
    3  -//
    4  -// Released as open source by NCC Group Plc - https://www.nccgroup.trust/
    5  -//
    6  -// Developed by Soroush Dalili (@irsdl)
    7  -//
    8  -// Project link: http://www.github.com/nccgroup/BurpSuiteLoggerPlusPlus
    9  -//
    10  -// Released under AGPL see LICENSE for more information
    11  -//
    12  - 
    13  -package burp;
    14  - 
    15  -import com.nccgroup.loggerplusplus.LoggerPlusPlus;
    16  - 
    17  - 
    18  -public class BurpExtender extends LoggerPlusPlus
    19  -{
    20  - public static void main(String [] args){
    21  - System.out.println("You have built the Logger++. You shall play with the jar file now!");
    22  - }
    23  -}
    24  - 
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/LoggerContextMenuFactory.java
    1 1  package com.nccgroup.loggerplusplus;
    2 2   
    3  -import burp.IContextMenuFactory;
    4  -import burp.IContextMenuInvocation;
    5  -import com.nccgroup.loggerplusplus.filter.colorfilter.ColorFilter;
    6  -import com.nccgroup.loggerplusplus.filter.logfilter.LogFilter;
    7  -import com.nccgroup.loggerplusplus.filter.parser.ParseException;
     3 +import burp.api.montoya.core.Range;
     4 +import burp.api.montoya.http.message.HttpMessage;
     5 +import burp.api.montoya.ui.contextmenu.ContextMenuEvent;
     6 +import burp.api.montoya.ui.contextmenu.ContextMenuItemsProvider;
     7 +import burp.api.montoya.ui.contextmenu.MessageEditorHttpRequestResponse;
     8 +import com.nccgroup.loggerplusplus.filter.colorfilter.TableColorRule;
    8 9  import com.nccgroup.loggerplusplus.logentry.LogEntryField;
    9 10  import com.nccgroup.loggerplusplus.logview.logtable.LogTable;
    10 11  import com.nccgroup.loggerplusplus.util.userinterface.dialog.ColorFilterDialog;
    11 12  import org.apache.commons.text.StringEscapeUtils;
    12 13   
    13 14  import javax.swing.*;
     15 +import java.awt.*;
    14 16  import java.awt.event.ActionEvent;
    15 17  import java.util.Arrays;
    16 18  import java.util.HashMap;
    skipped 2 lines
    19 21   
    20 22  import static com.nccgroup.loggerplusplus.util.Globals.PREF_COLOR_FILTERS;
    21 23   
    22  -public class LoggerContextMenuFactory implements IContextMenuFactory {
     24 +public class LoggerContextMenuFactory implements ContextMenuItemsProvider {
    23 25  
    24  - private final LoggerPlusPlus loggerPlusPlus;
    25  -
    26  - public LoggerContextMenuFactory(LoggerPlusPlus loggerPlusPlus){
    27  - this.loggerPlusPlus = loggerPlusPlus;
     26 + public LoggerContextMenuFactory(){
    28 27   }
    29 28   
    30 29   @Override
    31  - public List<JMenuItem> createMenuItems(IContextMenuInvocation invocation) {
    32  - if(invocation == null) return null;
     30 + public List<Component> provideMenuItems(ContextMenuEvent event) {
    33 31   JMenuItem filterMenu = new JMenu("Logger++");
    34 32   
    35  - if (invocation.getSelectedMessages().length == 0 ||
    36  - invocation.getSelectionBounds()[0] == invocation.getSelectionBounds()[1]) {
    37  - return null;
    38  - }
     33 + //We're handling a message editor context menu
     34 + //And we have a selection
     35 + MessageEditorHttpRequestResponse requestResponse = event.messageEditorRequestResponse().orElseThrow();
     36 + Range selectedRange = requestResponse.selectionOffsets().orElseThrow();
     37 + HttpMessage target;
    39 38   
    40 39   final LogEntryField context;
    41 40   final byte[] selectedBytes;
    42  - switch (invocation.getInvocationContext()){
    43  - case IContextMenuInvocation.CONTEXT_MESSAGE_EDITOR_REQUEST:
    44  - case IContextMenuInvocation.CONTEXT_MESSAGE_VIEWER_REQUEST: {
     41 + switch (event.invocationType()){
     42 + case MESSAGE_EDITOR_REQUEST:
     43 + case MESSAGE_VIEWER_REQUEST: {
     44 + target = requestResponse.requestResponse().request();
    45 45   try {
    46  - byte[] msg = invocation.getSelectedMessages()[0].getRequest();
    47  - if (LoggerPlusPlus.callbacks.getHelpers().analyzeRequest(msg).getBodyOffset() > invocation.getSelectionBounds()[0]) {
     46 + if (selectedRange.startIndexInclusive() <= target.bodyOffset()) {
    48 47   context = LogEntryField.REQUEST_HEADERS;
    49 48   } else {
    50 49   context = LogEntryField.REQUEST_BODY;
    51 50   }
    52  - selectedBytes = Arrays.copyOfRange(invocation.getSelectedMessages()[0].getRequest(),
    53  - invocation.getSelectionBounds()[0],invocation.getSelectionBounds()[1]);
     51 + selectedBytes = Arrays.copyOfRange(target.toByteArray().getBytes(), selectedRange.startIndexInclusive(),
     52 + selectedRange.endIndexExclusive());
    54 53   }catch (NullPointerException nPException){ return null; }
    55 54   break;
    56 55   }
    57 56   
    58  - case IContextMenuInvocation.CONTEXT_MESSAGE_EDITOR_RESPONSE:
    59  - case IContextMenuInvocation.CONTEXT_MESSAGE_VIEWER_RESPONSE: {
     57 + case MESSAGE_EDITOR_RESPONSE:
     58 + case MESSAGE_VIEWER_RESPONSE: {
     59 + target = requestResponse.requestResponse().response();
    60 60   try {
    61  - byte[] msg = invocation.getSelectedMessages()[0].getResponse();
    62  - if (LoggerPlusPlus.callbacks.getHelpers().analyzeRequest(msg).getBodyOffset() > invocation.getSelectionBounds()[0]) {
     61 + if (selectedRange.startIndexInclusive() <= target.bodyOffset()) {
    63 62   context = LogEntryField.RESPONSE_HEADERS;
    64 63   } else {
    65 64   context = LogEntryField.RESPONSE_BODY;
    66 65   }
    67  - selectedBytes = Arrays.copyOfRange(invocation.getSelectedMessages()[0].getResponse(),
    68  - invocation.getSelectionBounds()[0], invocation.getSelectionBounds()[1]);
     66 + selectedBytes = Arrays.copyOfRange(target.toByteArray().getBytes(), selectedRange.startIndexInclusive(),
     67 + selectedRange.endIndexExclusive());
    69 68   } catch (NullPointerException nPException) {
    70 69   return null;
    71 70   }
    skipped 3 lines
    75 74   return null;
    76 75   }
    77 76   
    78  - if (selectedBytes != null) System.out.println(new String(selectedBytes));
    79  - 
    80  - final LogTable logTable = loggerPlusPlus.getLogViewController().getLogTableController().getLogTable();
     77 + final LogTable logTable = LoggerPlusPlus.instance.getLogViewController().getLogTableController().getLogTable();
    81 78   String selectedText = StringEscapeUtils.escapeJava(new String(selectedBytes));
    82 79   
    83 80   JMenuItem useAsFilter = new JMenuItem(new AbstractAction("Use Selection As LogFilter") {
    84 81   @Override
    85 82   public void actionPerformed(ActionEvent actionEvent) {
    86  - loggerPlusPlus.getLogViewController().getLogFilterController().setFilter(context.getFullLabel() +
     83 + LoggerPlusPlus.instance.getLogViewController().getLogFilterController().setFilter(context.getFullLabel() +
    87 84   " CONTAINS \"" + selectedText + "\"");
    88 85   }
    89 86   });
    skipped 5 lines
    95 92   JMenuItem andFilter = new JMenuItem(new AbstractAction("AND") {
    96 93   @Override
    97 94   public void actionPerformed(ActionEvent actionEvent) {
    98  - loggerPlusPlus.getLogViewController().getLogFilterController().setFilter(logTable.getCurrentFilter().toString() + " && "
     95 + LoggerPlusPlus.instance.getLogViewController().getLogFilterController().setFilter(logTable.getCurrentFilter().toString() + " && "
    99 96   + "" + context.getFullLabel() + " CONTAINS \"" + selectedText + "\"");
    100 97   }
    101 98   });
    skipped 1 lines
    103 100   JMenuItem andNotFilter = new JMenuItem(new AbstractAction("AND NOT") {
    104 101   @Override
    105 102   public void actionPerformed(ActionEvent actionEvent) {
    106  - loggerPlusPlus.getLogViewController().getLogFilterController().setFilter(logTable.getCurrentFilter().toString() + " && !("
     103 + LoggerPlusPlus.instance.getLogViewController().getLogFilterController().setFilter(logTable.getCurrentFilter().toString() + " && !("
    107 104   + "" + context.getFullLabel() + " CONTAINS \"" + selectedText + "\")");
    108 105   }
    109 106   });
    skipped 1 lines
    111 108   JMenuItem orFilter = new JMenuItem(new AbstractAction("OR") {
    112 109   @Override
    113 110   public void actionPerformed(ActionEvent actionEvent) {
    114  - loggerPlusPlus.getLogViewController().getLogFilterController().setFilter(logTable.getCurrentFilter().toString() + " || "
     111 + LoggerPlusPlus.instance.getLogViewController().getLogFilterController().setFilter(logTable.getCurrentFilter().toString() + " || "
    115 112   + context.getFullLabel() + " CONTAINS \"" + selectedText + "\"");
    116 113   }
    117 114   });
    skipped 3 lines
    121 118   filterMenu.add(addToCurrentFilter);
    122 119   }
    123 120   
    124  - JMenuItem colorFilterItem = new JMenuItem(new AbstractAction("Set Selection as Color LogFilter") {
     121 + JMenuItem colorFilterItem = new JMenuItem(new AbstractAction("Set Selection as Color Filter") {
    125 122   @Override
    126 123   public void actionPerformed(ActionEvent actionEvent) {
    127  - try {
    128  - ColorFilter colorFilter = new ColorFilter();
    129  - colorFilter.setFilter(new LogFilter(loggerPlusPlus.getLibraryController(),
    130  - context.getFullLabel() + " CONTAINS \"" + selectedText + "\""));
    131  - HashMap<UUID,ColorFilter> colorFilters = loggerPlusPlus.getPreferencesController().getPreferences().getSetting(PREF_COLOR_FILTERS);
    132  - colorFilters.put(colorFilter.getUUID(), colorFilter);
    133  - new ColorFilterDialog(loggerPlusPlus.getLibraryController()).setVisible(true);
    134  - } catch (ParseException e) {
    135  - return;
    136  - }
     124 + TableColorRule tableColorRule = new TableColorRule("New Filter", context.getFullLabel() + " CONTAINS \"" + selectedText + "\"");
     125 + HashMap<UUID, TableColorRule> colorFilters = LoggerPlusPlus.instance.getPreferencesController().getPreferences().getSetting(PREF_COLOR_FILTERS);
     126 + colorFilters.put(tableColorRule.getUuid(), tableColorRule);
     127 + new ColorFilterDialog(LoggerPlusPlus.instance.getLibraryController()).setVisible(true);
    137 128   }
    138 129   });
    139 130   filterMenu.add(colorFilterItem);
    skipped 4 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/LoggerPlusPlus.java
    1 1  package com.nccgroup.loggerplusplus;
    2 2   
    3  -import burp.IBurpExtender;
    4  -import burp.IBurpExtenderCallbacks;
    5  -import burp.IExtensionStateListener;
     3 +import burp.api.montoya.BurpExtension;
     4 +import burp.api.montoya.MontoyaApi;
    6 5  import com.coreyd97.BurpExtenderUtilities.DefaultGsonProvider;
    7 6  import com.coreyd97.BurpExtenderUtilities.IGsonProvider;
    8 7  import com.nccgroup.loggerplusplus.exports.ExportController;
    skipped 7 lines
    16 15  import com.nccgroup.loggerplusplus.reflection.ReflectionController;
    17 16  import com.nccgroup.loggerplusplus.util.Globals;
    18 17  import com.nccgroup.loggerplusplus.util.userinterface.LoggerMenu;
     18 +import lombok.Getter;
     19 +import lombok.extern.log4j.Log4j2;
    19 20  import org.apache.logging.log4j.Level;
    20 21   
    21 22  import javax.swing.*;
    22 23  import java.awt.*;
    23  -import java.net.URL;
    24 24  import java.util.Arrays;
    25 25  import java.util.List;
    26  -import java.util.stream.Collectors;
    27 26   
    28 27  import static com.nccgroup.loggerplusplus.util.Globals.PREF_RESTRICT_TO_SCOPE;
    29 28   
    30 29  /**
    31 30   * Created by corey on 07/09/17.
    32 31   */
    33  -public class LoggerPlusPlus implements IBurpExtender, IExtensionStateListener {
     32 +@Log4j2
     33 +@Getter
     34 +public class LoggerPlusPlus implements BurpExtension {
     35 + 
     36 + private static String NAME = "Logger++";
     37 + 
     38 + public static LoggingController loggingController;
    34 39   public static LoggerPlusPlus instance;
    35  - public static IBurpExtenderCallbacks callbacks;
     40 + public static MontoyaApi montoya;
     41 + public static IGsonProvider gsonProvider = new DefaultGsonProvider();
    36 42   
    37  - private final IGsonProvider gsonProvider;
    38  - private LoggingController loggingController;
    39 43   private LogProcessor logProcessor;
    40 44   private ExportController exportController;
    41 45   private PreferencesController preferencesController;
    skipped 7 lines
    49 53   //UX
    50 54   private LoggerMenu loggerMenu;
    51 55   
    52  - 
    53  - public LoggerPlusPlus(){
    54  - this.gsonProvider = new DefaultGsonProvider();
    55  - }
    56  - 
    57  - private JFrame getBurpFrame() throws Exception {
    58  - // Get all frames
    59  - Frame[] allFrames = JFrame.getFrames();
    60  - // Filter the stream find the main burp window frame, and convert to a list
    61  - List<Frame> filteredFrames = Arrays.stream(allFrames).filter(f ->
    62  - f.getTitle().startsWith("Burp Suite") && f.isVisible()
    63  - ).collect(Collectors.toList());
    64  - // If size is 1, we have the main burp frame. Otherwise fails
    65  - if (filteredFrames.size() == 1) {
    66  - return (JFrame) filteredFrames.get(0);
    67  - } else {
    68  - throw new Exception("Expected one burp pane, but found " + filteredFrames.size());
    69  - }
     56 + public LoggerPlusPlus() {
     57 + LoggerPlusPlus.instance = this;
    70 58   }
    71 59   
    72 60   @Override
    73  - public void registerExtenderCallbacks(final IBurpExtenderCallbacks callbacks)
    74  - {
    75  - 
    76  - //Fix Darcula's issue with JSpinner UI.
    77  - try {
    78  - Class spinnerUI = Class.forName("com.bulenkov.darcula.ui.DarculaSpinnerUI");
    79  - UIManager.put("com.bulenkov.darcula.ui.DarculaSpinnerUI", spinnerUI);
    80  - Class sliderUI = Class.forName("com.bulenkov.darcula.ui.DarculaSliderUI");
    81  - UIManager.put("com.bulenkov.darcula.ui.DarculaSliderUI", sliderUI);
    82  - } catch (ClassNotFoundException e) {
    83  - //Darcula is not installed.
    84  - }
     61 + public void initialize(MontoyaApi montoya) {
     62 + //Woohoo! Montoya!
     63 + LoggerPlusPlus.montoya = montoya;
     64 + montoya.extension().setName(NAME);
     65 + montoya.extension().registerUnloadingHandler(this::unloadExtension);
    85 66   
    86  - //Burp Specific
    87  - LoggerPlusPlus.instance = this;
    88  - LoggerPlusPlus.callbacks = callbacks;
    89  - callbacks.setExtensionName("Logger++");
    90  - LoggerPlusPlus.callbacks.registerExtensionStateListener(LoggerPlusPlus.this);
     67 + //TODO Set Logging Level from prefs
     68 + loggingController = new LoggingController(gsonProvider, montoya);
     69 + log.info("Logging configured");
    91 70   
    92  - loggingController = new LoggingController(gsonProvider);
    93  - preferencesController = new PreferencesController(this);
     71 + preferencesController = new PreferencesController(montoya);
    94 72   preferencesController.getPreferences().addSettingListener((source, settingName, newValue) -> {
    95 73   if (settingName.equals(Globals.PREF_LOG_LEVEL)) {
    96 74   loggingController.setLogLevel((Level) newValue);
    97 75   }
    98 76   });
    99 77   reflectionController = new ReflectionController(preferencesController.getPreferences());
    100  - exportController = new ExportController(this, preferencesController.getPreferences());
    101  - libraryController = new FilterLibraryController(this, preferencesController);
    102  - logViewController = new LogViewController(this, libraryController);
    103  - logProcessor = new LogProcessor(this, logViewController.getLogTableController(), exportController);
    104  - grepperController = new GrepperController(this, logViewController.getLogTableController(), preferencesController);
    105  - contextMenuFactory = new LoggerContextMenuFactory(this);
     78 + exportController = new ExportController(preferencesController.getPreferences());
     79 + libraryController = new FilterLibraryController(preferencesController);
     80 + logViewController = new LogViewController(libraryController);
     81 + logProcessor = new LogProcessor(logViewController.getLogTableController(), exportController);
     82 + grepperController = new GrepperController(logViewController.getLogTableController(), preferencesController);
     83 + contextMenuFactory = new LoggerContextMenuFactory();
     84 + mainViewController = new MainViewController();
    106 85   
    107  - mainViewController = new MainViewController(this);
    108 86   
    109  - LoggerPlusPlus.callbacks.registerContextMenuFactory(contextMenuFactory);
     87 + montoya.userInterface().registerContextMenuItemsProvider(contextMenuFactory);
     88 + montoya.userInterface().registerSuiteTab(NAME, mainViewController.getUiComponent());
    110 89   
    111  - 
    112  - SwingUtilities.invokeLater(() -> {
    113  - 
    114  - LoggerPlusPlus.callbacks.addSuiteTab(mainViewController);
     90 + montoya.http().registerHttpHandler(logProcessor.getHttpHandler());
     91 + montoya.proxy().registerResponseHandler(logProcessor.getProxyResponseHandler());
    115 92   
    116  - //Add menu item to Burp's frame menu.
    117  - JFrame rootFrame = null;
    118  - try {
    119  - rootFrame = getBurpFrame();
    120  - } catch (Exception e) {
    121  - callbacks.printError("Could not find root frame. Window JMenu will not be added");
    122  - throw new RuntimeException(e);
    123  - }
    124  - try{
    125  - JMenuBar menuBar = rootFrame.getJMenuBar();
    126  - loggerMenu = new LoggerMenu(LoggerPlusPlus.this);
    127  - menuBar.add(loggerMenu, menuBar.getMenuCount() - 1);
    128  - }catch (NullPointerException nPException){
    129  - loggerMenu = null;
     93 + //Add menu item to Burp's frame menu.
     94 + Frame rootFrame = null;
     95 + try {
     96 + rootFrame = montoya.userInterface().swingUtils().suiteFrame();
     97 + if (rootFrame instanceof JFrame) {
     98 + JMenuBar menuBar = ((JFrame) rootFrame).getJMenuBar();
     99 + if (menuBar != null) {
     100 + loggerMenu = new LoggerMenu(LoggerPlusPlus.this);
     101 + menuBar.add(loggerMenu, menuBar.getMenuCount() - 1);
     102 + }
    130 103   }
    131  - });
    132  - 
     104 + } catch (Exception e) {
     105 + log.error("Could not find root frame. Window JMenu will not be added");
     106 + }
    133 107   }
    134 108   
    135  - @Override
    136  - public void extensionUnloaded() {
     109 + public void unloadExtension() {
    137 110   if(loggerMenu != null && loggerMenu.getParent() != null){
    138 111   loggerMenu.getParent().remove(loggerMenu);
    139 112   }
    skipped 9 lines
    149 122   
    150 123   //Null out static variables so not leftover.
    151 124   LoggerPlusPlus.instance = null;
    152  - LoggerPlusPlus.callbacks = null;
    153 125   }
    154 126   
    155  - public static boolean isUrlInScope(URL url){
     127 + public static boolean isUrlInScope(String url){
    156 128   return (!(Boolean) instance.getPreferencesController().getPreferences().getSetting(PREF_RESTRICT_TO_SCOPE)
    157  - || callbacks.isInScope(url));
    158  - }
    159  - 
    160  - 
    161  - public LogViewController getLogViewController() {
    162  - return logViewController;
    163  - }
    164  - 
    165  - public IGsonProvider getGsonProvider() {
    166  - return gsonProvider;
    167  - }
    168  - 
    169  - public GrepperController getGrepperController() {
    170  - return grepperController;
    171  - }
    172  - 
    173  - public MainViewController getMainViewController() {
    174  - return mainViewController;
    175  - }
    176  - 
    177  - public FilterLibraryController getLibraryController() {
    178  - return libraryController;
    179  - }
    180  - 
    181  - public LoggingController getLoggingController() {
    182  - return loggingController;
    183  - }
    184  - 
    185  - public PreferencesController getPreferencesController() {
    186  - return preferencesController;
    187  - }
    188  - 
    189  - public LogProcessor getLogProcessor() {
    190  - return logProcessor;
    191  - }
    192  - 
    193  - public ReflectionController getReflectionController() {
    194  - return reflectionController;
    195  - }
    196  - 
    197  - public LoggerMenu getLoggerMenu() {
    198  - return loggerMenu;
     129 + || montoya.scope().isInScope(url));
    199 130   }
    200 131   
    201 132   public List<LogEntry> getLogEntries(){
    202 133   return logViewController.getLogTableController().getLogTableModel().getData();
    203  - }
    204  - 
    205  - public ExportController getExportController() {
    206  - return exportController;
    207 134   }
    208 135   
    209 136   public Frame getLoggerFrame() {
    skipped 9 lines
  • ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/MainViewController.java
    1 1  package com.nccgroup.loggerplusplus;
    2 2   
    3  -import burp.ITab;
    4 3  import com.coreyd97.BurpExtenderUtilities.PopOutPanel;
    5 4  import com.nccgroup.loggerplusplus.about.AboutPanel;
    6 5  import com.nccgroup.loggerplusplus.help.HelpPanel;
    skipped 2 lines
    9 8  import javax.swing.*;
    10 9  import java.awt.*;
    11 10   
    12  -public class MainViewController implements ITab {
     11 +public class MainViewController {
    13 12  
    14  - private final LoggerPlusPlus loggerPlusPlus;
    15 13   private final JTabbedPane tabbedPane;
    16 14   private final PopOutPanel popOutWrapper;
    17 15   
    18  - public MainViewController(LoggerPlusPlus loggerPlusPlus) {
    19  - this.loggerPlusPlus = loggerPlusPlus;
     16 + public MainViewController() {
    20 17   this.tabbedPane = new JTabbedPane();
     18 + LoggerPlusPlus loggerPlusPlus = LoggerPlusPlus.instance;
    21 19   tabbedPane.addTab("View Logs", null, loggerPlusPlus.getLogViewController().getLogViewPanel(), null);
    22 20   tabbedPane.addTab("Filter Library", null, loggerPlusPlus.getLibraryController().getFilterLibraryPanel(), null);
    23 21   tabbedPane.addTab("Grep Values", null, loggerPlusPlus.getGrepperController().getGrepperPanel(), null);
    skipped 3 lines
    27 25   this.popOutWrapper = new PopOutPanel(tabbedPane, Globals.APP_NAME);
    28 26   }
    29 27   
    30  - @Override
    31  - public String getTabCaption() {
    32  - return Globals.APP_NAME;
    33  - }
    34  - 
    35  - @Override
    36 28   public Component getUiComponent() {
    37 29   return popOutWrapper;
    38 30   }
    skipped 10 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/exports/AutomaticLogExporter.java
    skipped 2 lines
    3 3  import com.coreyd97.BurpExtenderUtilities.Preferences;
    4 4  import com.nccgroup.loggerplusplus.logentry.LogEntry;
    5 5   
    6  -import javax.swing.*;
    7  - 
    8 6  public abstract class AutomaticLogExporter extends LogExporter {
    9 7   
    10 8   protected AutomaticLogExporter(ExportController exportController, Preferences preferences){
    skipped 29 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/exports/Base64Exporter.java
    skipped 38 lines
    39 39   protected Void doInBackground() throws Exception {
    40 40   super.doInBackground();
    41 41   try (FileWriter fileWriter = new FileWriter(file, false)) {
    42  - Gson gson = exportController.getLoggerPlusPlus().getGsonProvider().getGson();
     42 + Gson gson = LoggerPlusPlus.gsonProvider.getGson();
    43 43   ArrayList<JsonObject> jsonEntries = new ArrayList<>();
    44 44   Base64.Encoder encoder = Base64.getEncoder();
    45 45   for (LogEntry entry : entries) {
    46 46   JsonObject jsonEntry = new JsonObject();
    47 47   if (includeRequest) {
    48 48   jsonEntry.addProperty("request",
    49  - encoder.encodeToString(entry.getRequest()));
     49 + encoder.encodeToString(entry.getRequestBytes()));
    50 50   }
    51 51   
    52 52   if (includeResponse) {
    53 53   jsonEntry.addProperty("response",
    54  - encoder.encodeToString(entry.getResponse()));
     54 + encoder.encodeToString(entry.getResponseBytes()));
    55 55   }
    56 56   jsonEntries.add(jsonEntry);
    57 57   }
    skipped 57 lines
  • ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/exports/CSVExporterControlPanel.java
    skipped 1 lines
    2 2   
    3 3  import com.coreyd97.BurpExtenderUtilities.Alignment;
    4 4  import com.coreyd97.BurpExtenderUtilities.PanelBuilder;
     5 +import com.nccgroup.loggerplusplus.LoggerPlusPlus;
    5 6  import com.nccgroup.loggerplusplus.logentry.LogEntry;
    6 7   
    7 8  import javax.swing.*;
    skipped 11 lines
    19 20   
    20 21   JButton manualSaveButton = new JButton("Export as CSV");
    21 22   manualSaveButton.addActionListener(actionEvent -> {
    22  - final List<LogEntry> entries = csvExporter.getExportController().getLoggerPlusPlus().getLogEntries();
     23 + final List<LogEntry> entries = LoggerPlusPlus.instance.getLogEntries();
    23 24   csvExporter.exportEntries(entries);
    24 25   });
    25 26   
    skipped 41 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/exports/ElasticExporter.java
    skipped 1 lines
    2 2   
    3 3  import com.coreyd97.BurpExtenderUtilities.Preferences;
    4 4  import com.nccgroup.loggerplusplus.LoggerPlusPlus;
    5  -import com.nccgroup.loggerplusplus.filter.logfilter.LogFilter;
     5 +import com.nccgroup.loggerplusplus.filter.logfilter.LogTableFilter;
    6 6  import com.nccgroup.loggerplusplus.filter.parser.ParseException;
    7 7  import com.nccgroup.loggerplusplus.logentry.LogEntry;
    8 8  import com.nccgroup.loggerplusplus.logentry.LogEntryField;
    9 9  import com.nccgroup.loggerplusplus.logentry.Status;
    10 10  import com.nccgroup.loggerplusplus.util.Globals;
     11 +import lombok.extern.log4j.Log4j2;
    11 12  import org.apache.commons.lang3.StringUtils;
    12 13  import org.apache.http.Header;
    13 14  import org.apache.http.HttpHost;
    skipped 26 lines
    40 41   
    41 42  import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
    42 43   
     44 +@Log4j2
    43 45  public class ElasticExporter extends AutomaticLogExporter implements ExportPanelProvider, ContextMenuExportProvider {
    44 46   
    45 47   RestHighLevelClient httpClient;
    46 48   ArrayList<LogEntry> pendingEntries;
    47  - LogFilter logFilter;
     49 + LogTableFilter logFilter;
    48 50   private List<LogEntryField> fields;
    49 51   private String indexName;
    50 52   private ScheduledFuture indexTask;
    skipped 44 lines
    95 97   
    96 98   if (!StringUtils.isBlank(filterString)) {
    97 99   try {
    98  - logFilter = new LogFilter(exportController.getLoggerPlusPlus().getLibraryController(), filterString);
     100 + logFilter = new LogTableFilter(filterString);
    99 101   } catch (ParseException ex) {
    100 102   logger.error("The log filter configured for the Elastic exporter is invalid!", ex);
    101 103   }
    skipped 39 lines
    141 143   @Override
    142 144   public void exportNewEntry(final LogEntry logEntry) {
    143 145   if(logEntry.getStatus() == Status.PROCESSED) {
    144  - if (logFilter != null && !logFilter.matches(logEntry)) return;
     146 + if (logFilter != null && !logFilter.getFilterExpression().matches(logEntry)) return;
    145 147   pendingEntries.add(logEntry);
    146 148   }
    147 149   }
    skipped 1 lines
    149 151   @Override
    150 152   public void exportUpdatedEntry(final LogEntry updatedEntry) {
    151 153   if(updatedEntry.getStatus() == Status.PROCESSED) {
    152  - if (logFilter != null && !logFilter.matches(updatedEntry)) return;
     154 + if (logFilter != null && !logFilter.getFilterExpression().matches(updatedEntry)) return;
    153 155   pendingEntries.add(updatedEntry);
    154 156   }
    155 157   }
    skipped 41 lines
    197 199   builder.field(field.getFullLabel(), value);
    198 200   }
    199 201   }catch (Exception e){
    200  - LoggerPlusPlus.callbacks.printError("ElasticExporter: " + value);
    201  - LoggerPlusPlus.callbacks.printError("ElasticExporter: " + e.getMessage());
     202 + log.error("ElasticExporter: " + value);
     203 + log.error("ElasticExporter: " + e.getMessage());
    202 204   throw e;
    203 205   }
    204 206   }
    skipped 19 lines
    224 226   IndexRequest request = buildIndexRequest(logEntry);
    225 227   httpBulkBuilder.add(request);
    226 228   } catch (Exception e) {
    227  - LoggerPlusPlus.callbacks.printError("Could not build elastic export request for entry: " + e.getMessage());
     229 + log.error("Could not build elastic export request for entry: " + e.getMessage());
    228 230   //Could not build index request. Ignore it?
    229 231   }
    230 232   }
    skipped 2 lines
    233 235   BulkResponse bulkResponse = httpClient.bulk(httpBulkBuilder, RequestOptions.DEFAULT);
    234 236   if (bulkResponse.hasFailures()) {
    235 237   for (BulkItemResponse bulkItemResponse : bulkResponse.getItems()) {
    236  - LoggerPlusPlus.callbacks.printError(bulkItemResponse.getFailureMessage());
     238 + log.error(bulkItemResponse.getFailureMessage());
    237 239   }
    238 240   }
    239 241   connectFailedCounter = 0;
    skipped 35 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/exports/ElasticExporterConfigDialog.java
    skipped 4 lines
    5 5  import com.coreyd97.BurpExtenderUtilities.PanelBuilder;
    6 6  import com.coreyd97.BurpExtenderUtilities.Preferences;
    7 7  import com.nccgroup.loggerplusplus.LoggerPlusPlus;
    8  -import com.nccgroup.loggerplusplus.filter.logfilter.LogFilter;
     8 +import com.nccgroup.loggerplusplus.filter.logfilter.LogTableFilter;
    9 9  import com.nccgroup.loggerplusplus.filter.parser.ParseException;
    10 10  import com.nccgroup.loggerplusplus.filterlibrary.FilterLibraryController;
    11 11  import com.nccgroup.loggerplusplus.logentry.LogEntryField;
    skipped 209 lines
    221 221   String logFilter = preferences.getSetting(PREF_ELASTIC_FILTER);
    222 222   
    223 223   if (!StringUtils.isBlank(logFilter)) {
    224  - FilterLibraryController libraryController = elasticExporter.getExportController()
    225  - .getLoggerPlusPlus().getLibraryController();
    226 224   try {
    227  - new LogFilter(libraryController, logFilter);
     225 + new LogTableFilter(logFilter);
    228 226   } catch (ParseException ex) {
    229 227   JOptionPane.showMessageDialog(ElasticExporterConfigDialog.this,
    230 228   "Cannot save Elastic Exporter configuration. The chosen log filter is invalid: \n" +
    skipped 11 lines
  • ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/exports/ExportController.java
    1 1  package com.nccgroup.loggerplusplus.exports;
    2 2   
    3 3  import com.coreyd97.BurpExtenderUtilities.Preferences;
    4  -import com.nccgroup.loggerplusplus.LoggerPlusPlus;
    5 4  import com.nccgroup.loggerplusplus.logentry.LogEntry;
    6 5   
    7 6  import java.util.ArrayList;
    skipped 2 lines
    10 9  import java.util.List;
    11 10   
    12 11  public class ExportController {
    13  - 
    14  - private final LoggerPlusPlus loggerPlusPlus;
    15 12   private final Preferences preferences;
    16 13   private final HashMap<Class<? extends LogExporter>, LogExporter> exporters;
    17 14   private final List<AutomaticLogExporter> enabledExporters;
    18 15   
    19  - public ExportController(LoggerPlusPlus loggerPlusPlus, Preferences preferences) {
    20  - this.loggerPlusPlus = loggerPlusPlus;
     16 + public ExportController(Preferences preferences) {
    21 17   this.preferences = preferences;
    22 18   
    23 19   this.exporters = new HashMap<>();
    skipped 38 lines
    62 58   for (AutomaticLogExporter exporter : this.enabledExporters) {
    63 59   exporter.exportUpdatedEntry(logEntry);
    64 60   }
    65  - }
    66  - 
    67  - public LoggerPlusPlus getLoggerPlusPlus() {
    68  - return loggerPlusPlus;
    69 61   }
    70 62  }
    71 63   
  • ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/exports/HARExporterControlPanel.java
    skipped 1 lines
    2 2   
    3 3  import com.coreyd97.BurpExtenderUtilities.Alignment;
    4 4  import com.coreyd97.BurpExtenderUtilities.PanelBuilder;
     5 +import com.nccgroup.loggerplusplus.LoggerPlusPlus;
    5 6  import com.nccgroup.loggerplusplus.logentry.LogEntry;
    6 7   
    7 8  import javax.swing.*;
    skipped 6 lines
    14 15   
    15 16   JButton manualSaveButton = new JButton("Export as HAR");
    16 17   manualSaveButton.addActionListener(actionEvent -> {
    17  - final List<LogEntry> entries = harExporter.getExportController().getLoggerPlusPlus().getLogEntries();
     18 + final List<LogEntry> entries = LoggerPlusPlus.instance.getLogEntries();
    18 19   harExporter.exportEntries(entries);
    19 20   });
    20 21   
    skipped 6 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/exports/HarSerializer.java
    1 1  package com.nccgroup.loggerplusplus.exports;
    2 2   
    3  -import burp.ICookie;
    4  -import burp.IParameter;
    5  -import burp.IRequestInfo;
    6  -import burp.IResponseInfo;
     3 +import burp.api.montoya.http.message.Cookie;
     4 +import burp.api.montoya.http.message.HttpHeader;
     5 +import burp.api.montoya.http.message.params.HttpParameter;
     6 +import burp.api.montoya.http.message.params.HttpParameterType;
     7 +import burp.api.montoya.http.message.requests.HttpRequest;
    7 8  import com.google.gson.TypeAdapter;
    8 9  import com.google.gson.stream.JsonReader;
    9 10  import com.google.gson.stream.JsonWriter;
    10  -import com.nccgroup.loggerplusplus.LoggerPlusPlus;
    11 11  import com.nccgroup.loggerplusplus.logentry.LogEntry;
    12 12  import com.nccgroup.loggerplusplus.logentry.LogEntryField;
    13 13   
    skipped 46 lines
    60 60   writer.name("time").value(time);
    61 61   writer.name("request").beginObject();
    62 62   writer.name("method").value(logEntry.getMethod());
    63  - writer.name("url").value(logEntry.getUrl().toString());
     63 + writer.name("url").value(logEntry.getUrlString().toString());
    64 64   writer.name("httpVersion").value(logEntry.getRequestHttpVersion());
    65 65   writer.name("origin").value(logEntry.getOrigin());
    66 66   
    67 67   writer.name("cookies").beginArray();
    68 68   if (logEntry.isHasCookieParam()) {
    69  - List<IParameter> cookies = getRequestParametersByType(logEntry.getRequest(),
    70  - IParameter.PARAM_COOKIE);
    71  - for (IParameter cookie : cookies) {
     69 + List<HttpParameter> cookies = getRequestParametersByType(logEntry.getRequest(), HttpParameterType.COOKIE);
     70 + for (HttpParameter cookie : cookies) {
    72 71   writer.beginObject();
    73  - writer.name("name").value(cookie.getName());
    74  - writer.name("value").value(cookie.getValue());
     72 + writer.name("name").value(cookie.name());
     73 + writer.name("value").value(cookie.value());
    75 74   writer.endObject();
    76 75   }
    77 76   }
    78 77   writer.endArray(); // end request cookies array
    79 78   
    80 79   writer.name("headers").beginArray();
    81  - for (String headerString : logEntry.getRequestHeaders()) {
    82  - if (headerString.contains(":")) {
    83  - writer.beginObject();
    84  - String headerArray[] = headerString.split(":", 2);
    85  - writer.name("name").value(headerArray[0]);
    86  - writer.name("value").value(headerArray[1].trim());
    87  - writer.endObject();
    88  - }
     80 + for (HttpHeader header : logEntry.getRequestHeaders()) {
     81 + writer.beginObject();
     82 + writer.name("name").value(header.name());
     83 + writer.name("value").value(header.value());
     84 + writer.endObject();
    89 85   }
    90 86   writer.endArray(); // end request headers array
    91 87   
    92 88   writer.name("queryString").beginArray();
    93 89   if (logEntry.getUrl().getQuery() != null) {
    94  - List<IParameter> queryParams = getRequestParametersByType(logEntry.getRequest(),
    95  - IParameter.PARAM_URL);
    96  - for (IParameter queryParam : queryParams) {
     90 + for (HttpParameter queryParam : getRequestParametersByType(logEntry.getRequest(), HttpParameterType.URL)) {
    97 91   writer.beginObject();
    98  - writer.name("name").value(queryParam.getName());
    99  - writer.name("value").value(queryParam.getValue());
     92 + writer.name("name").value(queryParam.name());
     93 + writer.name("value").value(queryParam.value());
    100 94   writer.endObject();
    101 95   }
    102 96   }
    skipped 2 lines
    105 99   if (logEntry.isHasBodyParam()) {
    106 100   writer.name("postData").beginObject();
    107 101   writer.name("mimeType").value(logEntry.getRequestContentType());
    108  - List<IParameter> bodyParams = getRequestBodyParameters(logEntry.getRequest());
    109 102   writer.name("params").beginArray();
    110  - for (IParameter bodyParam : bodyParams) {
     103 + for (HttpParameter bodyParam : getRequestParametersByType(logEntry.getRequest(), HttpParameterType.BODY)) {
    111 104   writer.beginObject();
    112  - writer.name("name").value(bodyParam.getName());
    113  - writer.name("value").value(bodyParam.getValue());
     105 + writer.name("name").value(bodyParam.name());
     106 + writer.name("value").value(bodyParam.value());
    114 107   writer.endObject();
    115 108   }
    116 109   writer.endArray(); // end params array
    skipped 1 lines
    118 111   writer.endObject(); // end postData object
    119 112   }
    120 113   
    121  - writer.name("headersSize").value(logEntry.getRequest().length - logEntry.getRequestBodyLength());
     114 + writer.name("headersSize").value(logEntry.getRequestBytes().length - logEntry.getRequestBodyLength());
    122 115   writer.name("bodySize").value(logEntry.getRequestBodyLength());
    123 116   
    124 117   writer.endObject(); // end request object
    skipped 5 lines
    130 123   
    131 124   writer.name("cookies").beginArray();
    132 125   if (logEntry.isHasSetCookies()) {
    133  - List<ICookie> cookies = getResponseCookies(logEntry.getResponse());
     126 + List<Cookie> cookies = logEntry.getResponse().cookies();
    134 127   
    135  - for (ICookie cookie : cookies) {
     128 + for (Cookie cookie : cookies) {
    136 129   writer.beginObject();
    137  - writer.name("name").value(cookie.getName());
    138  - writer.name("value").value(cookie.getValue());
    139  - writer.name("path").value(cookie.getPath());
    140  - writer.name("domain").value(cookie.getDomain());
     130 + writer.name("name").value(cookie.name());
     131 + writer.name("value").value(cookie.value());
     132 + writer.name("path").value(cookie.path());
     133 + writer.name("domain").value(cookie.domain());
    141 134   writer.endObject();
    142 135   }
    143 136   }
    skipped 1 lines
    145 138   
    146 139   writer.name("headers").beginArray();
    147 140   if (logEntry.getResponseHeaders() != null) {
    148  - for (String headerString : logEntry.getResponseHeaders()) {
    149  - if (headerString.contains(":")) {
    150  - writer.beginObject();
    151  - String headerArray[] = headerString.split(":", 2);
    152  - writer.name("name").value(headerArray[0]);
    153  - writer.name("value").value(headerArray[1].trim());
    154  - writer.endObject();
    155  - }
     141 + for (HttpHeader header : logEntry.getResponseHeaders()) {
     142 + writer.beginObject();
     143 + writer.name("name").value(header.name());
     144 + writer.name("value").value(header.value());
     145 + writer.endObject();
    156 146   }
    157 147   }
    158 148   writer.endArray(); // end response headers array
    159 149   
    160 150   writer.name("redirectURL").value(String.valueOf(logEntry.getValueByKey(LogEntryField.REDIRECT_URL)));
    161  - if (logEntry.getResponse() != null) {
    162  - writer.name("headersSize").value(logEntry.getResponse().length - logEntry.getResponseBodyLength());
     151 + if (logEntry.getResponseBytes() != null) {
     152 + writer.name("headersSize").value(logEntry.getResponseBytes().length - logEntry.getResponseBodyLength());
    163 153   writer.name("bodySize").value(logEntry.getResponseBodyLength());
    164 154   } else {
    165 155   writer.name("headersSize").value(0);
    skipped 3 lines
    169 159   
    170 160   writer.name("content").beginObject(); // start content object
    171 161   writer.name("size").value(logEntry.getResponseBodyLength());
    172  - writer.name("mimeType").value(logEntry.getResponseMimeType());
     162 + writer.name("mimeType").value(logEntry.getResponseContentType());
    173 163   writer.name("text").value(String.valueOf(logEntry.getValueByKey(LogEntryField.RESPONSE_BODY)));
    174 164   writer.endObject(); //end content object
    175 165   
    skipped 19 lines
    195 185   
    196 186   }
    197 187   
    198  - private List<IParameter> getRequestParametersByType(byte[] request, byte paramType) {
    199  - IRequestInfo tempAnalyzedReq = LoggerPlusPlus.callbacks.getHelpers().analyzeRequest(request);
    200  - List<IParameter> params = tempAnalyzedReq.getParameters().stream()
    201  - .filter(iParameter -> iParameter.getType() == paramType).collect(Collectors.toList());
    202  - return params;
    203  - }
    204  - 
    205  - private List<IParameter> getRequestBodyParameters(byte[] request) {
    206  - IRequestInfo tempAnalyzedReq = LoggerPlusPlus.callbacks.getHelpers().analyzeRequest(request);
    207  - List<IParameter> params = tempAnalyzedReq.getParameters().stream()
    208  - .filter(iParameter -> iParameter.getType() != IParameter.PARAM_COOKIE
    209  - && iParameter.getType() != IParameter.PARAM_URL)
     188 + private List<HttpParameter> getRequestParametersByType(HttpRequest request, HttpParameterType paramType) {
     189 + return request.parameters().stream()
     190 + .filter(iParameter -> iParameter.type().equals(paramType))
    210 191   .collect(Collectors.toList());
    211  - return params;
    212 192   }
     193 + 
    213 194   
    214 195   @Override
    215 196   public List<LogEntry> read(JsonReader reader) throws IOException {
    216 197   // TODO Implement HAR Import logic
    217 198   return null;
    218  - }
    219  - 
    220  - private List<ICookie> getResponseCookies(byte[] responseMessage) {
    221  - IResponseInfo tempAnalyzedResp = LoggerPlusPlus.callbacks.getHelpers().analyzeResponse(responseMessage);
    222  - 
    223  - return tempAnalyzedResp.getCookies();
    224 199   }
    225 200   
    226 201  }
    skipped 1 lines
  • ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/exports/JSONExporter.java
    skipped 1 lines
    2 2   
    3 3  import com.coreyd97.BurpExtenderUtilities.Preferences;
    4 4  import com.google.gson.Gson;
     5 +import com.nccgroup.loggerplusplus.LoggerPlusPlus;
    5 6  import com.nccgroup.loggerplusplus.logentry.LogEntry;
    6 7  import com.nccgroup.loggerplusplus.util.MoreHelp;
    7 8  import com.nccgroup.loggerplusplus.util.SwingWorkerWithProgressDialog;
    skipped 33 lines
    41 42   protected Void doInBackground() throws Exception {
    42 43   super.doInBackground();
    43 44   try(FileWriter fileWriter = new FileWriter(file, false)) {
    44  - Gson gson = exportController.getLoggerPlusPlus().getGsonProvider().getGson();
     45 + Gson gson = LoggerPlusPlus.gsonProvider.getGson();
    45 46   gson.toJson(entries, fileWriter);
    46 47   }
    47 48   
    skipped 34 lines
  • ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/exports/JSONExporterControlPanel.java
    skipped 1 lines
    2 2   
    3 3  import com.coreyd97.BurpExtenderUtilities.Alignment;
    4 4  import com.coreyd97.BurpExtenderUtilities.PanelBuilder;
     5 +import com.nccgroup.loggerplusplus.LoggerPlusPlus;
    5 6  import com.nccgroup.loggerplusplus.logentry.LogEntry;
    6 7   
    7 8  import javax.swing.*;
    skipped 7 lines
    15 16   
    16 17   JButton manualSaveButton = new JButton("Export as JSON");
    17 18   manualSaveButton.addActionListener(actionEvent -> {
    18  - final List<LogEntry> entries = jsonExporter.getExportController().getLoggerPlusPlus().getLogEntries();
     19 + final List<LogEntry> entries = LoggerPlusPlus.instance.getLogEntries();
    19 20   jsonExporter.exportEntries(entries);
    20 21   });
    21 22   
    skipped 11 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/filter/ColorizingFilterRule.java
     1 +package com.nccgroup.loggerplusplus.filter;
     2 + 
     3 +import com.google.gson.annotations.JsonAdapter;
     4 +import com.nccgroup.loggerplusplus.filter.colorfilter.TableColorRule;
     5 +import lombok.Getter;
     6 +import lombok.Setter;
     7 + 
     8 +import java.awt.*;
     9 + 
     10 +public abstract class ColorizingFilterRule extends FilterRule {
     11 + 
     12 + @Getter @Setter
     13 + private Color backgroundColor;
     14 + @Getter @Setter
     15 + private Color foregroundColor;
     16 + @Getter @Setter
     17 + private short priority;
     18 + @Getter @Setter
     19 + private boolean enabled;
     20 + 
     21 + protected ColorizingFilterRule(String name){
     22 + super(name);
     23 + }
     24 + 
     25 + protected ColorizingFilterRule(String name, FilterExpression filterExpression){
     26 + super(name, filterExpression);
     27 + }
     28 + 
     29 + protected ColorizingFilterRule(String name, String filter){
     30 + super(name, filter);
     31 + }
     32 + 
     33 + @Override
     34 + public boolean equals(Object obj) {
     35 + if(obj instanceof ColorizingFilterRule){
     36 + return ((ColorizingFilterRule) obj).getUuid().equals(this.getUuid());
     37 + }else{
     38 + return super.equals(obj);
     39 + }
     40 + }
     41 +}
     42 + 
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/filter/FilterExpression.java
     1 +package com.nccgroup.loggerplusplus.filter;
     2 + 
     3 +import com.nccgroup.loggerplusplus.LoggerPlusPlus;
     4 +import com.nccgroup.loggerplusplus.filter.parser.*;
     5 +import com.nccgroup.loggerplusplus.logentry.LogEntry;
     6 +import com.nccgroup.loggerplusplus.logentry.LogEntryField;
     7 +import lombok.Getter;
     8 + 
     9 +import java.util.HashSet;
     10 + 
     11 +public class FilterExpression {
     12 + 
     13 + @Getter
     14 + protected ASTExpression ast;
     15 + 
     16 + @Getter
     17 + protected HashSet<String> snippetDependencies;
     18 + 
     19 + public FilterExpression(String filterString) throws ParseException {
     20 + this.ast = FilterParser.parseFilter(filterString);
     21 + this.snippetDependencies = FilterParser.checkAliasesForSanity(LoggerPlusPlus.instance.getLibraryController(), this.ast);
     22 + }
     23 + 
     24 + public boolean matches(LogEntry entry){
     25 + FilterEvaluationVisitor visitor = new FilterEvaluationVisitor(LoggerPlusPlus.instance.getLibraryController());
     26 + return visitor.visit(ast, entry);
     27 + }
     28 + 
     29 + public void addConditionToFilter(LogicalOperator logicalOperator, LogEntryField field,
     30 + ComparisonOperator booleanOperator, String value) throws ParseException {
     31 + String existing;
     32 + if (this.ast.getLogicalOperator() != null && !this.ast.getLogicalOperator().equals(logicalOperator)) {
     33 + existing = "(" + this.ast.getFilterString() + ")";
     34 + } else {
     35 + existing = this.ast.getFilterString();
     36 + }
     37 + 
     38 + this.ast = FilterParser.parseFilter(String.format("%s %s %s %s %s", existing, logicalOperator.toString(), field.toString(), booleanOperator, value));
     39 + this.snippetDependencies = FilterParser.checkAliasesForSanity(LoggerPlusPlus.instance.getLibraryController(), this.ast);
     40 + }
     41 + 
     42 + @Override
     43 + public String toString() {
     44 + return ast.getFilterString();
     45 + }
     46 +}
     47 + 
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/filter/FilterExpressionSerializer.java
     1 +package com.nccgroup.loggerplusplus.filter;
     2 + 
     3 +import com.google.gson.*;
     4 +import com.nccgroup.loggerplusplus.filter.parser.ParseException;
     5 + 
     6 +import java.lang.reflect.Type;
     7 + 
     8 +public class FilterExpressionSerializer implements JsonSerializer<FilterExpression>, JsonDeserializer<FilterExpression> {
     9 + 
     10 + @Override
     11 + public JsonElement serialize(FilterExpression filter, Type type, JsonSerializationContext jsonSerializationContext) {
     12 + JsonObject object = new JsonObject();
     13 + object.addProperty("filter", filter.toString());
     14 + return object;
     15 + }
     16 + 
     17 + @Override
     18 + public FilterExpression deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
     19 + FilterExpression filter = null;
     20 + try {
     21 + filter = new FilterExpression(jsonElement.getAsJsonObject().get("filter").getAsString());
     22 + } catch (ParseException e) {
     23 + }
     24 + return filter;
     25 + }
     26 +}
     27 + 
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/filter/FilterRule.java
     1 +package com.nccgroup.loggerplusplus.filter;
     2 + 
     3 +import com.google.gson.annotations.SerializedName;
     4 +import com.nccgroup.loggerplusplus.filter.parser.ParseException;
     5 +import lombok.Getter;
     6 + 
     7 +import java.util.UUID;
     8 + 
     9 +public abstract class FilterRule {
     10 + 
     11 + @Getter @SerializedName("uid")
     12 + private UUID uuid;
     13 + @Getter
     14 + private String name;
     15 + @Getter
     16 + private String filterString;
     17 + @Getter @SerializedName("filter")
     18 + private FilterExpression filterExpression;
     19 + 
     20 + public FilterRule(String name){
     21 + this.name = name;
     22 + this.uuid = UUID.randomUUID();
     23 + }
     24 + 
     25 + public FilterRule(String name, FilterExpression filterExpression){
     26 + this(name);
     27 + this.filterExpression = filterExpression;
     28 + this.filterString = filterExpression.toString();
     29 + }
     30 + 
     31 + public FilterRule(String name, String filterString){
     32 + this(name);
     33 + trySetFilter(filterString);
     34 + }
     35 + 
     36 + protected void setUuid(UUID uuid) {
     37 + this.uuid = uuid;
     38 + }
     39 + 
     40 + public void setFilter(FilterExpression expression) {
     41 + this.filterExpression = expression;
     42 + if(expression != null) this.filterString = expression.toString();
     43 + }
     44 + 
     45 + public void setName(String name){
     46 + this.name = name;
     47 + }
     48 + 
     49 + public boolean trySetFilter(String filterString){
     50 + this.filterString = filterString;
     51 + try{
     52 + parseAndSetFilter(filterString);
     53 + }catch (ParseException e){
     54 + return false;
     55 + }
     56 + 
     57 + return true;
     58 + }
     59 + 
     60 + public void parseAndSetFilter(String filterString) throws ParseException {
     61 + this.filterString = filterString;
     62 + this.filterExpression = new FilterExpression(filterString);
     63 + }
     64 +}
     65 + 
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/filter/SavedFilterSerializer.java
     1 +package com.nccgroup.loggerplusplus.filter;
     2 + 
     3 +import com.google.gson.*;
     4 +import com.nccgroup.loggerplusplus.filter.savedfilter.SavedFilter;
     5 + 
     6 +import java.lang.reflect.Type;
     7 +import java.util.UUID;
     8 + 
     9 +public class SavedFilterSerializer implements JsonSerializer<SavedFilter>, JsonDeserializer<SavedFilter> {
     10 + 
     11 + @Override
     12 + public JsonElement serialize(SavedFilter tag, Type type, JsonSerializationContext context) {
     13 + JsonObject object = new JsonObject();
     14 + object.addProperty("uid", tag.getUuid().toString());
     15 + object.addProperty("name", tag.getName());
     16 + object.add("filter", context.serialize(tag.getFilterExpression()));
     17 + return object;
     18 + }
     19 + 
     20 + @Override
     21 + public SavedFilter deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext context) throws JsonParseException {
     22 + JsonObject obj = jsonElement.getAsJsonObject();
     23 + String uid = obj.get("uid").getAsString();
     24 + String name = obj.get("name").getAsString();
     25 + FilterExpression filterExpression = context.deserialize(obj.get("filter"), FilterExpression.class);
     26 +
     27 + SavedFilter tag = new SavedFilter(name, filterExpression);
     28 + tag.setUuid(UUID.fromString(uid));
     29 + return tag;
     30 + }
     31 +}
     32 + 
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/filter/TableColorRuleSerializer.java
     1 +package com.nccgroup.loggerplusplus.filter;
     2 + 
     3 +import com.google.gson.*;
     4 +import com.nccgroup.loggerplusplus.filter.colorfilter.TableColorRule;
     5 + 
     6 +import java.awt.*;
     7 +import java.lang.reflect.Type;
     8 +import java.util.UUID;
     9 + 
     10 +public class TableColorRuleSerializer implements JsonSerializer<TableColorRule>, JsonDeserializer<TableColorRule> {
     11 + 
     12 + @Override
     13 + public JsonElement serialize(TableColorRule tag, Type type, JsonSerializationContext context) {
     14 + JsonObject object = new JsonObject();
     15 + object.addProperty("uid", tag.getUuid().toString());
     16 + object.addProperty("name", tag.getName());
     17 + object.add("filter", context.serialize(tag.getFilterExpression()));
     18 + object.add("foregroundColor", context.serialize(tag.getForegroundColor()));
     19 + object.add("backgroundColor", context.serialize(tag.getBackgroundColor()));
     20 + object.addProperty("enabled", tag.isEnabled());
     21 + object.addProperty("priority", tag.getPriority());
     22 + return object;
     23 + }
     24 + 
     25 + @Override
     26 + public TableColorRule deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext context) throws JsonParseException {
     27 + JsonObject obj = jsonElement.getAsJsonObject();
     28 + String uid = obj.get("uid").getAsString();
     29 + String name = obj.has("name") ? obj.get("name").getAsString() : "";
     30 + FilterExpression filterExpression = context.deserialize(obj.get("filter"), FilterExpression.class);
     31 + Color foregroundColor = context.deserialize(obj.get("foregroundColor"), Color.class);
     32 + Color backgroundColor = context.deserialize(obj.get("backgroundColor"), Color.class);
     33 + boolean enabled = obj.get("enabled").getAsBoolean();
     34 + short priority = obj.get("priority").getAsShort();
     35 +
     36 + TableColorRule tag = new TableColorRule(name, filterExpression);
     37 + tag.setUuid(UUID.fromString(uid));
     38 + tag.setForegroundColor(foregroundColor);
     39 + tag.setBackgroundColor(backgroundColor);
     40 + tag.setEnabled(enabled);
     41 + tag.setPriority(priority);
     42 + return tag;
     43 + }
     44 +}
     45 + 
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/filter/TagSerializer.java
     1 +package com.nccgroup.loggerplusplus.filter;
     2 + 
     3 +import com.google.gson.*;
     4 +import com.nccgroup.loggerplusplus.filter.parser.ParseException;
     5 +import com.nccgroup.loggerplusplus.filter.tag.Tag;
     6 + 
     7 +import java.awt.*;
     8 +import java.lang.reflect.Type;
     9 +import java.util.UUID;
     10 + 
     11 +public class TagSerializer implements JsonSerializer<Tag>, JsonDeserializer<Tag> {
     12 + 
     13 + @Override
     14 + public JsonElement serialize(Tag tag, Type type, JsonSerializationContext context) {
     15 + JsonObject object = new JsonObject();
     16 + object.addProperty("uid", tag.getUuid().toString());
     17 + object.addProperty("name", tag.getName());
     18 + object.add("filter", context.serialize(tag.getFilterExpression()));
     19 + object.add("foregroundColor", context.serialize(tag.getForegroundColor()));
     20 + object.add("backgroundColor", context.serialize(tag.getBackgroundColor()));
     21 + object.addProperty("enabled", tag.isEnabled());
     22 + object.addProperty("priority", tag.getPriority());
     23 + return object;
     24 + }
     25 + 
     26 + @Override
     27 + public Tag deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext context) throws JsonParseException {
     28 + JsonObject obj = jsonElement.getAsJsonObject();
     29 + String uid = obj.get("uid").getAsString();
     30 + String name = obj.get("name").getAsString();
     31 + FilterExpression filterExpression = context.deserialize(obj.get("filter"), FilterExpression.class);
     32 + Color foregroundColor = context.deserialize(obj.get("foregroundColor"), Color.class);
     33 + Color backgroundColor = context.deserialize(obj.get("backgroundColor"), Color.class);
     34 + boolean enabled = obj.get("enabled").getAsBoolean();
     35 + short priority = obj.get("priority").getAsShort();
     36 +
     37 + Tag tag = new Tag(name, filterExpression);
     38 + tag.setUuid(UUID.fromString(uid));
     39 + tag.setForegroundColor(foregroundColor);
     40 + tag.setBackgroundColor(backgroundColor);
     41 + tag.setEnabled(enabled);
     42 + tag.setPriority(priority);
     43 + return tag;
     44 + }
     45 +}
     46 + 
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/filter/colorfilter/ColorFilter.java
    1  -package com.nccgroup.loggerplusplus.filter.colorfilter;
    2  - 
    3  -import com.nccgroup.loggerplusplus.filter.logfilter.LogFilter;
    4  -import com.nccgroup.loggerplusplus.filter.logfilter.LogFilterController;
    5  -import com.nccgroup.loggerplusplus.filter.parser.ParseException;
    6  -import com.nccgroup.loggerplusplus.filterlibrary.FilterLibraryController;
    7  - 
    8  -import java.awt.*;
    9  -import java.util.UUID;
    10  - 
    11  -/**
    12  - * Created by corey on 19/07/17.
    13  - */
    14  -public class ColorFilter implements Comparable<ColorFilter>{
    15  - private UUID uid;
    16  - private String name;
    17  - private LogFilter filter;
    18  - private String filterString;
    19  - private Color backgroundColor;
    20  - private Color foregroundColor;
    21  - private boolean enabled;
    22  - private boolean modified;
    23  - private boolean shouldRetest;
    24  - private short priority;
    25  - 
    26  - public ColorFilter(){
    27  - this.uid = UUID.randomUUID();
    28  - this.enabled = true;
    29  - this.shouldRetest = true;
    30  - }
    31  - 
    32  - public ColorFilter(String title, LogFilter filter) {
    33  - this();
    34  - this.name = title;
    35  - this.setFilter(filter);
    36  - }
    37  - 
    38  - public ColorFilter(FilterLibraryController filterLibraryController, String title, String filterString) throws ParseException {
    39  - this(title, new LogFilter(filterLibraryController, filterString));
    40  - }
    41  - 
    42  - public ColorFilter(String title, LogFilter filter, Color foreground, Color background){
    43  - this(title, filter);
    44  - this.foregroundColor = foreground;
    45  - this.backgroundColor = background;
    46  - }
    47  - 
    48  - public UUID getUUID() {
    49  - return uid;
    50  - }
    51  - 
    52  - public void setBackgroundColor(Color backgroundColor){
    53  - this.backgroundColor = backgroundColor;
    54  - this.modified = true;
    55  - }
    56  - 
    57  - public Color getBackgroundColor() {
    58  - return backgroundColor;
    59  - }
    60  - 
    61  - public Color getForegroundColor() {return foregroundColor;}
    62  - 
    63  - public void setForegroundColor(Color foregroundColor) {
    64  - this.foregroundColor = foregroundColor;
    65  - modified = true;
    66  - }
    67  - 
    68  - public LogFilter getFilter() {
    69  - return filter;
    70  - }
    71  - 
    72  - public void setFilter(LogFilter filter) {
    73  - this.filter = filter;
    74  - if(filter != null)
    75  - this.filterString = filter.toString();
    76  - modified = true;
    77  - shouldRetest = true;
    78  - }
    79  - 
    80  - public String getName() {
    81  - return name;
    82  - }
    83  - 
    84  - public void setName(String name) {
    85  - this.name = name;
    86  - }
    87  - 
    88  - public boolean isEnabled() {
    89  - return enabled;
    90  - }
    91  - 
    92  - public void setEnabled(boolean enabled) {
    93  - this.enabled = enabled;
    94  - modified = true;
    95  - shouldRetest = true;
    96  - }
    97  - 
    98  - public String getFilterString() {
    99  - return filterString;
    100  - }
    101  - 
    102  - public void setFilterString(String filterString) {
    103  - this.filterString = filterString;
    104  - }
    105  - 
    106  - public boolean equals(Object obj){
    107  - if(obj instanceof ColorFilter){
    108  - return ((ColorFilter) obj).getUUID().equals(this.uid);
    109  - }else{
    110  - return super.equals(obj);
    111  - }
    112  - }
    113  - 
    114  - public boolean isModified() {
    115  - return modified;
    116  - }
    117  - 
    118  - public void setModified(boolean modified) {
    119  - this.modified = modified;
    120  - }
    121  - 
    122  - public void setPriority(short priority){
    123  - this.priority = priority;
    124  - this.modified = true;
    125  - }
    126  - 
    127  - public short getPriority() {
    128  - return priority;
    129  - }
    130  - 
    131  - @Override
    132  - public int compareTo(ColorFilter colorFilter) {
    133  - return ((Comparable) this.priority).compareTo(colorFilter.getPriority());
    134  - }
    135  - 
    136  - public boolean shouldRetest() {
    137  - return shouldRetest;
    138  - }
    139  - 
    140  - @Override
    141  - public String toString() {
    142  - return "ColorFilter[" + (this.filter != null ? this.filter.toString() : "") + "]";
    143  - }
    144  -}
    145  - 
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/filter/colorfilter/ColorFilterListener.java
    skipped 4 lines
    5 5   */
    6 6  public interface ColorFilterListener {
    7 7   
    8  - void onColorFilterChange(ColorFilter filter);
     8 + void onColorFilterChange(TableColorRule filter);
    9 9   
    10  - void onColorFilterAdd(ColorFilter filter);
     10 + void onColorFilterAdd(TableColorRule filter);
    11 11   
    12  - void onColorFilterRemove(ColorFilter filter);
     12 + void onColorFilterRemove(TableColorRule filter);
    13 13  }
    14 14   
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/filter/colorfilter/TableColorRule.java
     1 +package com.nccgroup.loggerplusplus.filter.colorfilter;
     2 + 
     3 +import com.nccgroup.loggerplusplus.filter.ColorizingFilterRule;
     4 +import com.nccgroup.loggerplusplus.filter.FilterExpression;
     5 +import com.nccgroup.loggerplusplus.filter.logfilter.LogTableFilter;
     6 +import com.nccgroup.loggerplusplus.filter.parser.ParseException;
     7 +import com.nccgroup.loggerplusplus.filterlibrary.FilterLibraryController;
     8 +import lombok.AccessLevel;
     9 +import lombok.Getter;
     10 +import org.elasticsearch.common.Table;
     11 + 
     12 +import java.awt.*;
     13 +import java.util.HashSet;
     14 +import java.util.Set;
     15 +import java.util.UUID;
     16 + 
     17 +/**
     18 + * Created by corey on 19/07/17.
     19 + */
     20 +public class TableColorRule extends ColorizingFilterRule implements Comparable<TableColorRule>{
     21 + 
     22 + @Getter(AccessLevel.PUBLIC)
     23 + private boolean shouldRetest = true;
     24 + 
     25 + public TableColorRule(){
     26 + super("", "");
     27 + }
     28 + 
     29 + public TableColorRule(String title, String filterString) {
     30 + super(title, filterString);
     31 + }
     32 + 
     33 + public TableColorRule(String title, FilterExpression filterExpression) {
     34 + super(title, filterExpression);
     35 + }
     36 + 
     37 + @Override
     38 + public boolean trySetFilter(String filterString){
     39 + boolean success = super.trySetFilter(filterString);
     40 + if(success) shouldRetest = true;
     41 + return success;
     42 + }
     43 + 
     44 + @Override
     45 + public void setFilter(FilterExpression filter) {
     46 + super.setFilter(filter);
     47 + shouldRetest = true;
     48 + }
     49 + 
     50 + @Override
     51 + public void setEnabled(boolean enabled) {
     52 + super.setEnabled(enabled);
     53 + shouldRetest = true;
     54 + }
     55 + 
     56 + @Override
     57 + public int compareTo(TableColorRule tableColorRule) {
     58 + return ((Comparable) this.getPriority()).compareTo(tableColorRule.getPriority());
     59 + }
     60 + 
     61 + @Override
     62 + public String toString() {
     63 + return "ColorFilter[" + (this.getFilterExpression() != null ? this.getFilterExpression().toString() : getFilterString()) + "]";
     64 + }
     65 +}
     66 + 
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/filter/logfilter/LogFilter.java
    1  -package com.nccgroup.loggerplusplus.filter.logfilter;
    2  - 
    3  -import com.google.gson.*;
    4  -import com.nccgroup.loggerplusplus.LoggerPlusPlus;
    5  -import com.nccgroup.loggerplusplus.filter.ComparisonOperator;
    6  -import com.nccgroup.loggerplusplus.filter.LogicalOperator;
    7  -import com.nccgroup.loggerplusplus.filter.parser.ASTExpression;
    8  -import com.nccgroup.loggerplusplus.filter.parser.FilterEvaluationVisitor;
    9  -import com.nccgroup.loggerplusplus.filter.parser.FilterParser;
    10  -import com.nccgroup.loggerplusplus.filter.parser.ParseException;
    11  -import com.nccgroup.loggerplusplus.filterlibrary.FilterLibraryController;
    12  -import com.nccgroup.loggerplusplus.logentry.LogEntry;
    13  -import com.nccgroup.loggerplusplus.logentry.LogEntryField;
    14  -import com.nccgroup.loggerplusplus.logview.logtable.LogTableModel;
    15  - 
    16  -import javax.swing.*;
    17  -import javax.swing.table.TableModel;
    18  -import java.lang.reflect.Type;
    19  - 
    20  -public class LogFilter extends RowFilter<TableModel, Integer> {
    21  - 
    22  - private final ASTExpression filter;
    23  - 
    24  - public LogFilter(String filterString) throws ParseException {
    25  - filter = FilterParser.parseFilter(filterString);
    26  - }
    27  - 
    28  - public LogFilter(FilterLibraryController filterLibraryController, String filterString) throws ParseException {
    29  - this(filterString);
    30  - FilterParser.checkAliasesForSanity(filterLibraryController, this.filter);
    31  - }
    32  - 
    33  - public String addConditionToFilter(LogicalOperator logicalOperator, LogEntryField field,
    34  - ComparisonOperator booleanOperator, String value) {
    35  - //TODO Move functionality to LogFilter itself.
    36  - String existing;
    37  - if (this.getAST().getLogicalOperator() != null && !this.getAST().getLogicalOperator().equals(logicalOperator)) {
    38  - existing = "(" + this.filter.getFilterString() + ")";
    39  - } else {
    40  - existing = this.filter.getFilterString();
    41  - }
    42  - 
    43  - return String.format("%s %s %s %s %s", existing, logicalOperator.toString(), field.toString(), booleanOperator, value);
    44  - }
    45  - 
    46  - public ASTExpression getAST(){
    47  - return this.filter;
    48  - }
    49  - 
    50  - public boolean matches(LogEntry entry){
    51  - FilterEvaluationVisitor visitor = new FilterEvaluationVisitor(LoggerPlusPlus.instance.getLibraryController());
    52  - return visitor.visit(filter, entry);
    53  - }
    54  - 
    55  - @Override
    56  - public String toString() {
    57  - return filter.getFilterString();
    58  - }
    59  - 
    60  - @Override
    61  - public boolean include(Entry entry) {
    62  - int index = (int) entry.getIdentifier();
    63  - TableModel tableModel = (TableModel) entry.getModel();
    64  - if(tableModel instanceof LogTableModel){
    65  - LogEntry logEntry = ((LogTableModel) tableModel).getRow(index);
    66  - return this.matches(logEntry);
    67  - }
    68  - return false;
    69  - }
    70  - 
    71  - public static class FilterSerializer implements JsonSerializer<LogFilter>, JsonDeserializer<LogFilter> {
    72  - @Override
    73  - public JsonElement serialize(LogFilter filter, Type type, JsonSerializationContext jsonSerializationContext) {
    74  - JsonObject object = new JsonObject();
    75  - object.addProperty("filter", filter.toString());
    76  - return object;
    77  - }
    78  - 
    79  - @Override
    80  - public LogFilter deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
    81  - LogFilter filter = null;
    82  - try {
    83  - filter = new LogFilter(jsonElement.getAsJsonObject().get("filter").getAsString());
    84  - } catch (ParseException e) {}
    85  - return filter;
    86  - }
    87  - }
    88  - 
    89  -}
    90  - 
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/filter/logfilter/LogFilterController.java
    skipped 117 lines
    118 118   
    119 119   public void setFilter(final String filterString) {
    120 120   if (filterString == null || filterString.length() == 0 || filterString.matches(" +")) {
    121  - setFilter((LogFilter) null);
     121 + setFilter((LogTableFilter) null);
    122 122   } else {
    123 123   try {
    124  - LogFilter filter = new LogFilter(LoggerPlusPlus.instance.getLibraryController(), filterString);
     124 + LogTableFilter filter = new LogTableFilter(filterString);
    125 125   setFilter(filter);
    126 126   } catch (ParseException e) {
    127 127   logTable.setFilter(null);
    skipped 21 lines
    149 149   formatFilter("");
    150 150   }
    151 151   
    152  - private void setFilter(LogFilter filter) {
     152 + public void setFilter(LogTableFilter filter) {
    153 153   if (filter == null) {
    154 154   clearFilter();
    155 155   } else {
    156  - String filterString = filter.toString();
     156 + String filterString = filter.getFilterExpression().toString();
    157 157   formatFilter(filterString);
    158 158   logTable.setFilter(filter);
    159 159   }
    skipped 26 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/filter/logfilter/LogTableFilter.java
     1 +package com.nccgroup.loggerplusplus.filter.logfilter;
     2 + 
     3 +import com.nccgroup.loggerplusplus.filter.FilterExpression;
     4 +import com.nccgroup.loggerplusplus.filter.parser.ParseException;
     5 +import com.nccgroup.loggerplusplus.logentry.LogEntry;
     6 +import com.nccgroup.loggerplusplus.logview.logtable.LogTableModel;
     7 +import lombok.Getter;
     8 + 
     9 +import javax.swing.*;
     10 +import javax.swing.table.TableModel;
     11 + 
     12 +public class LogTableFilter extends RowFilter<TableModel, Integer> {
     13 + 
     14 + @Getter
     15 + private FilterExpression filterExpression;
     16 + 
     17 + public LogTableFilter(String filterString) throws ParseException {
     18 + this.filterExpression = new FilterExpression(filterString);
     19 + }
     20 + 
     21 + public LogTableFilter(FilterExpression filterExpression){
     22 + this.filterExpression = filterExpression;
     23 + }
     24 + 
     25 + @Override
     26 + public boolean include(RowFilter.Entry entry) {
     27 + int index = (int) entry.getIdentifier();
     28 + TableModel tableModel = (TableModel) entry.getModel();
     29 + if(tableModel instanceof LogTableModel){
     30 + LogEntry logEntry = ((LogTableModel) tableModel).getRow(index);
     31 + return filterExpression.matches(logEntry);
     32 + }
     33 + return false;
     34 + }
     35 +}
     36 + 
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/filter/parser/AliasCheckVisitor.java
    skipped 14 lines
    15 15   }
    16 16   
    17 17   public VisitorData defaultVisit(SimpleNode node, VisitorData data){
     18 + data.setData("dependencies", new HashSet<String>());
    18 19   node.childrenAccept(this, data);
    19 20   return data;
    20 21   }
    skipped 15 lines
    36 37   private static String RECURSION_CHECK = "RECURSION_CHECK";
    37 38   @Override
    38 39   public VisitorData visit(ASTAlias node, VisitorData data) {
     40 + ((HashSet<String>) data.getData().get("dependencies")).add(node.identifier);
    39 41   if(filterLibraryController == null){
    40 42   data.addError("Cannot use aliases in this context. Filter library controller is not set.");
    41 43   return data;
    skipped 13 lines
    55 57   
    56 58   //Now sanity check on the aliased filter with our existing data
    57 59   boolean foundAliasedFilter = false;
    58  - for (SavedFilter savedFilter : filterLibraryController.getSavedFilters()) {
    59  - if(savedFilter.getName().equalsIgnoreCase(node.identifier) && savedFilter.getFilter() != null){
    60  - visit(savedFilter.getFilter().getAST(), data);
     60 + for (SavedFilter savedFilter : filterLibraryController.getFilterSnippets()) {
     61 + if(savedFilter.getName().equalsIgnoreCase(node.identifier) && savedFilter.getFilterExpression() != null){
     62 + visit(savedFilter.getFilterExpression().getAst(), data);
    61 63   foundAliasedFilter = true;
    62 64   break;
    63 65   }
    skipped 11 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/filter/parser/Filter.jj
    skipped 11 lines
    12 12   
    13 13  PARSER_BEGIN(FilterParser)
    14 14  package com.nccgroup.loggerplusplus.filter.parser;
    15  -import com.nccgroup.loggerplusplus.filter.ComparisonOperator;import com.nccgroup.loggerplusplus.filter.LogicalOperator;
    16 15  import com.nccgroup.loggerplusplus.filter.ComparisonOperator;
     16 +import com.nccgroup.loggerplusplus.filter.LogicalOperator;
    17 17  import com.nccgroup.loggerplusplus.filterlibrary.FilterLibraryController;
    18 18  import java.io.StringReader;
    19 19  import java.math.BigDecimal;
    20 20  import java.util.Arrays;
    21 21  import java.util.LinkedHashSet;
     22 +import java.util.HashSet;
    22 23  import java.util.Set;
    23 24  import java.util.Date;
    24 25  import java.util.ArrayList;
    skipped 12 lines
    37 38   FilterParser FilterParser = new FilterParser(new StringReader(string));
    38 39   ASTExpression node;
    39 40   node = FilterParser.Filter();
    40  -// VisitorData result = new SanityCheckVisitor().visit(node);
    41  -// if(!result.isSuccess()) throw new ParseException(result.getErrorString());
    42 41   return node;
    43 42   }
    44 43   
    45  - public static void checkAliasesForSanity(FilterLibraryController libraryController, ASTExpression filter) throws ParseException {
     44 + public static HashSet<String> checkAliasesForSanity(FilterLibraryController libraryController, ASTExpression filter) throws ParseException {
    46 45   VisitorData result = new AliasCheckVisitor(libraryController).visit(filter);
    47 46   if(!result.isSuccess()) throw new ParseException(result.getErrorString());
     47 + return (HashSet<String>) result.getData().get("dependencies");
    48 48   }
    49 49   
    50 50   private static void throwOperatorAmbiguityException(LogicalOperator op, LogicalOperator other) throws ParseException {
    skipped 537 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/filter/parser/Filter.jjt
    skipped 10 lines
    11 11   
    12 12  PARSER_BEGIN(FilterParser)
    13 13  package com.nccgroup.loggerplusplus.filter.parser;
    14  -import com.nccgroup.loggerplusplus.filter.ComparisonOperator;import com.nccgroup.loggerplusplus.filter.LogicalOperator;
    15 14  import com.nccgroup.loggerplusplus.filter.ComparisonOperator;
     15 +import com.nccgroup.loggerplusplus.filter.LogicalOperator;
    16 16  import com.nccgroup.loggerplusplus.filterlibrary.FilterLibraryController;
    17 17  import java.io.StringReader;
    18 18  import java.math.BigDecimal;
    19 19  import java.util.Arrays;
    20 20  import java.util.LinkedHashSet;
     21 +import java.util.HashSet;
    21 22  import java.util.Set;
    22 23  import java.util.Date;
    23 24  import java.util.ArrayList;
    skipped 9 lines
    33 34   FilterParser FilterParser = new FilterParser(new StringReader(string));
    34 35   ASTExpression node;
    35 36   node = FilterParser.Filter();
    36  -// VisitorData result = new SanityCheckVisitor().visit(node);
    37  -// if(!result.isSuccess()) throw new ParseException(result.getErrorString());
    38 37   return node;
    39 38   }
    40 39   
    41  - public static void checkAliasesForSanity(FilterLibraryController libraryController, ASTExpression filter) throws ParseException {
     40 + public static HashSet<String> checkAliasesForSanity(FilterLibraryController libraryController, ASTExpression filter) throws ParseException {
    42 41   VisitorData result = new AliasCheckVisitor(libraryController).visit(filter);
    43 42   if(!result.isSuccess()) throw new ParseException(result.getErrorString());
     43 + return (HashSet<String>) result.getData().get("dependencies");
    44 44   }
    45 45   
    46 46   private static void throwOperatorAmbiguityException(LogicalOperator op, LogicalOperator other) throws ParseException {
    skipped 458 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/filter/parser/FilterEvaluationVisitor.java
    skipped 88 lines
    89 89   
    90 90   @Override
    91 91   public Boolean visit(ASTAlias node, VisitorData data) {
    92  - for (SavedFilter savedFilter : filterLibraryController.getSavedFilters()) {
     92 + for (SavedFilter savedFilter : filterLibraryController.getFilterSnippets()) {
    93 93   if(node.identifier.equalsIgnoreCase(savedFilter.getName())){
    94  - return visit(savedFilter.getFilter().getAST(), data);
     94 + return visit(savedFilter.getFilterExpression().getAst(), data);
    95 95   }
    96 96   }
    97 97   return false;
    skipped 96 lines
  • src/main/java/com/nccgroup/loggerplusplus/filter/parser/FilterParser.java
    Diff is too large to be displayed.
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/filter/parser/FilterParserTokenManager.java
    1 1  /* Generated By:JJTree&JavaCC: Do not edit this line. FilterParserTokenManager.java */
    2 2  package com.nccgroup.loggerplusplus.filter.parser;
     3 +import com.nccgroup.loggerplusplus.filter.ComparisonOperator;
     4 +import com.nccgroup.loggerplusplus.filter.LogicalOperator;
     5 +import com.nccgroup.loggerplusplus.filterlibrary.FilterLibraryController;
     6 +import java.io.StringReader;
     7 +import java.math.BigDecimal;
     8 +import java.util.Arrays;
     9 +import java.util.LinkedHashSet;
     10 +import java.util.HashSet;
     11 +import java.util.Set;
     12 +import java.util.Date;
     13 +import java.util.ArrayList;
     14 +import java.util.regex.Pattern;
     15 +import com.nccgroup.loggerplusplus.logentry.LogEntryField;
     16 +import com.nccgroup.loggerplusplus.logentry.FieldGroup;
     17 +import static com.nccgroup.loggerplusplus.logentry.LogEntryField.getFieldsInGroup;
     18 +import com.nccgroup.loggerplusplus.logview.processor.LogProcessor;
    3 19   
    4  -/**
    5  - * Token Manager.
    6  - */
    7  -public class FilterParserTokenManager implements FilterParserConstants {
     20 +/** Token Manager. */
     21 +public class FilterParserTokenManager implements FilterParserConstants
     22 +{
    8 23   
    9  - /** Debug output. */
    10  - public java.io.PrintStream debugStream = System.out;
    11  - 
    12  - /** Set debug output. */
    13  - public void setDebugStream(java.io.PrintStream ds) {
    14  - debugStream = ds;
    15  - }
    16  - 
    17  - private int jjStopAtPos(int pos, int kind) {
    18  - jjmatchedKind = kind;
    19  - jjmatchedPos = pos;
    20  - return pos + 1;
    21  - }
    22  - 
    23  - private int jjMoveStringLiteralDfa0_0() {
    24  - switch (curChar) {
    25  - case 32:
    26  - jjmatchedKind = 1;
    27  - return jjMoveNfa_0(0, 0);
    28  - case 33:
    29  - return jjMoveStringLiteralDfa1_0(0x8L);
    30  - case 34:
    31  - jjmatchedKind = 29;
    32  - return jjMoveNfa_0(0, 0);
     24 + /** Debug output. */
     25 + public java.io.PrintStream debugStream = System.out;
     26 + /** Set debug output. */
     27 + public void setDebugStream(java.io.PrintStream ds) { debugStream = ds; }
     28 +private int jjStopAtPos(int pos, int kind)
     29 +{
     30 + jjmatchedKind = kind;
     31 + jjmatchedPos = pos;
     32 + return pos + 1;
     33 +}
     34 +private int jjMoveStringLiteralDfa0_0()
     35 +{
     36 + switch(curChar)
     37 + {
     38 + case 32:
     39 + jjmatchedKind = 1;
     40 + return jjMoveNfa_0(0, 0);
     41 + case 33:
     42 + return jjMoveStringLiteralDfa1_0(0x8L);
     43 + case 34:
     44 + jjmatchedKind = 29;
     45 + return jjMoveNfa_0(0, 0);
    33 46   case 35:
    34 47   jjmatchedKind = 27;
    35 48   return jjMoveNfa_0(0, 0);
    skipped 30 lines
    66 79   case 93:
    67 80   jjmatchedKind = 25;
    68 81   return jjMoveNfa_0(0, 0);
    69  - case 99:
    70  - return jjMoveStringLiteralDfa1_0(0x800L);
    71  - case 105:
    72  - return jjMoveStringLiteralDfa1_0(0x1000L);
    73  - case 109:
    74  - return jjMoveStringLiteralDfa1_0(0x40000L);
    75  - default:
    76  - return jjMoveNfa_0(0, 0);
    77  - }
     82 + case 99:
     83 + return jjMoveStringLiteralDfa1_0(0x800L);
     84 + case 105:
     85 + return jjMoveStringLiteralDfa1_0(0x1000L);
     86 + case 109:
     87 + return jjMoveStringLiteralDfa1_0(0x40000L);
     88 + default :
     89 + return jjMoveNfa_0(0, 0);
     90 + }
     91 +}
     92 +private int jjMoveStringLiteralDfa1_0(long active0)
     93 +{
     94 + try { curChar = input_stream.readChar(); }
     95 + catch(java.io.IOException e) {
     96 + return jjMoveNfa_0(0, 0);
    78 97   }
    79  - 
    80  - private int jjMoveStringLiteralDfa1_0(long active0) {
    81  - try {
    82  - curChar = input_stream.readChar();
    83  - } catch (java.io.IOException e) {
    84  - return jjMoveNfa_0(0, 0);
    85  - }
    86  - switch (curChar) {
    87  - case 61:
    88  - if ((active0 & 0x8L) != 0L) {
    89  - jjmatchedKind = 3;
     98 + switch(curChar)
     99 + {
     100 + case 61:
     101 + if ((active0 & 0x8L) != 0L)
     102 + {
     103 + jjmatchedKind = 3;
    90 104   jjmatchedPos = 1;
    91 105   }
    92 106   else if ((active0 & 0x40L) != 0L)
    skipped 27 lines
    120 134   jjmatchedPos = 1;
    121 135   }
    122 136   break;
    123  - case 111:
    124  - return jjMoveStringLiteralDfa2_0(active0, 0x800L);
    125  - default:
    126  - break;
    127  - }
     137 + case 111:
     138 + return jjMoveStringLiteralDfa2_0(active0, 0x800L);
     139 + default :
     140 + break;
     141 + }
     142 + return jjMoveNfa_0(0, 1);
     143 +}
     144 +private int jjMoveStringLiteralDfa2_0(long old0, long active0)
     145 +{
     146 + if (((active0 &= old0)) == 0L)
    128 147   return jjMoveNfa_0(0, 1);
     148 + try { curChar = input_stream.readChar(); }
     149 + catch(java.io.IOException e) {
     150 + return jjMoveNfa_0(0, 1);
    129 151   }
    130  - 
    131  - private int jjMoveStringLiteralDfa2_0(long old0, long active0) {
    132  - if (((active0 &= old0)) == 0L)
    133  - return jjMoveNfa_0(0, 1);
    134  - try {
    135  - curChar = input_stream.readChar();
    136  - } catch (java.io.IOException e) {
    137  - return jjMoveNfa_0(0, 1);
    138  - }
    139  - switch (curChar) {
    140  - case 78:
    141  - return jjMoveStringLiteralDfa3_0(active0, 0x800L);
     152 + switch(curChar)
     153 + {
     154 + case 78:
     155 + return jjMoveStringLiteralDfa3_0(active0, 0x800L);
    142 156   case 84:
    143 157   return jjMoveStringLiteralDfa3_0(active0, 0x40000L);
    144  - case 110:
    145  - return jjMoveStringLiteralDfa3_0(active0, 0x800L);
    146  - case 116:
    147  - return jjMoveStringLiteralDfa3_0(active0, 0x40000L);
    148  - default:
    149  - break;
    150  - }
     158 + case 110:
     159 + return jjMoveStringLiteralDfa3_0(active0, 0x800L);
     160 + case 116:
     161 + return jjMoveStringLiteralDfa3_0(active0, 0x40000L);
     162 + default :
     163 + break;
     164 + }
     165 + return jjMoveNfa_0(0, 2);
     166 +}
     167 +private int jjMoveStringLiteralDfa3_0(long old0, long active0)
     168 +{
     169 + if (((active0 &= old0)) == 0L)
    151 170   return jjMoveNfa_0(0, 2);
     171 + try { curChar = input_stream.readChar(); }
     172 + catch(java.io.IOException e) {
     173 + return jjMoveNfa_0(0, 2);
    152 174   }
    153  - 
    154  - private int jjMoveStringLiteralDfa3_0(long old0, long active0) {
    155  - if (((active0 &= old0)) == 0L)
    156  - return jjMoveNfa_0(0, 2);
    157  - try {
    158  - curChar = input_stream.readChar();
    159  - } catch (java.io.IOException e) {
    160  - return jjMoveNfa_0(0, 2);
    161  - }
    162  - switch (curChar) {
    163  - case 67:
    164  - return jjMoveStringLiteralDfa4_0(active0, 0x40000L);
     175 + switch(curChar)
     176 + {
     177 + case 67:
     178 + return jjMoveStringLiteralDfa4_0(active0, 0x40000L);
    165 179   case 84:
    166 180   return jjMoveStringLiteralDfa4_0(active0, 0x800L);
    167  - case 99:
    168  - return jjMoveStringLiteralDfa4_0(active0, 0x40000L);
    169  - case 116:
    170  - return jjMoveStringLiteralDfa4_0(active0, 0x800L);
    171  - default:
    172  - break;
    173  - }
     181 + case 99:
     182 + return jjMoveStringLiteralDfa4_0(active0, 0x40000L);
     183 + case 116:
     184 + return jjMoveStringLiteralDfa4_0(active0, 0x800L);
     185 + default :
     186 + break;
     187 + }
     188 + return jjMoveNfa_0(0, 3);
     189 +}
     190 +private int jjMoveStringLiteralDfa4_0(long old0, long active0)
     191 +{
     192 + if (((active0 &= old0)) == 0L)
    174 193   return jjMoveNfa_0(0, 3);
     194 + try { curChar = input_stream.readChar(); }
     195 + catch(java.io.IOException e) {
     196 + return jjMoveNfa_0(0, 3);
    175 197   }
    176  - 
    177  - private int jjMoveStringLiteralDfa4_0(long old0, long active0) {
    178  - if (((active0 &= old0)) == 0L)
    179  - return jjMoveNfa_0(0, 3);
    180  - try {
    181  - curChar = input_stream.readChar();
    182  - } catch (java.io.IOException e) {
    183  - return jjMoveNfa_0(0, 3);
    184  - }
    185  - switch (curChar) {
    186  - case 65:
    187  - return jjMoveStringLiteralDfa5_0(active0, 0x800L);
     198 + switch(curChar)
     199 + {
     200 + case 65:
     201 + return jjMoveStringLiteralDfa5_0(active0, 0x800L);
    188 202   case 72:
    189 203   return jjMoveStringLiteralDfa5_0(active0, 0x40000L);
    190  - case 97:
    191  - return jjMoveStringLiteralDfa5_0(active0, 0x800L);
    192  - case 104:
    193  - return jjMoveStringLiteralDfa5_0(active0, 0x40000L);
    194  - default:
    195  - break;
    196  - }
     204 + case 97:
     205 + return jjMoveStringLiteralDfa5_0(active0, 0x800L);
     206 + case 104:
     207 + return jjMoveStringLiteralDfa5_0(active0, 0x40000L);
     208 + default :
     209 + break;
     210 + }
     211 + return jjMoveNfa_0(0, 4);
     212 +}
     213 +private int jjMoveStringLiteralDfa5_0(long old0, long active0)
     214 +{
     215 + if (((active0 &= old0)) == 0L)
    197 216   return jjMoveNfa_0(0, 4);
     217 + try { curChar = input_stream.readChar(); }
     218 + catch(java.io.IOException e) {
     219 + return jjMoveNfa_0(0, 4);
    198 220   }
    199  - 
    200  - private int jjMoveStringLiteralDfa5_0(long old0, long active0) {
    201  - if (((active0 &= old0)) == 0L)
    202  - return jjMoveNfa_0(0, 4);
    203  - try {
    204  - curChar = input_stream.readChar();
    205  - } catch (java.io.IOException e) {
    206  - return jjMoveNfa_0(0, 4);
    207  - }
    208  - switch (curChar) {
    209  - case 69:
    210  - return jjMoveStringLiteralDfa6_0(active0, 0x40000L);
     221 + switch(curChar)
     222 + {
     223 + case 69:
     224 + return jjMoveStringLiteralDfa6_0(active0, 0x40000L);
    211 225   case 73:
    212 226   return jjMoveStringLiteralDfa6_0(active0, 0x800L);
    213  - case 101:
    214  - return jjMoveStringLiteralDfa6_0(active0, 0x40000L);
    215  - case 105:
    216  - return jjMoveStringLiteralDfa6_0(active0, 0x800L);
    217  - default:
    218  - break;
    219  - }
     227 + case 101:
     228 + return jjMoveStringLiteralDfa6_0(active0, 0x40000L);
     229 + case 105:
     230 + return jjMoveStringLiteralDfa6_0(active0, 0x800L);
     231 + default :
     232 + break;
     233 + }
     234 + return jjMoveNfa_0(0, 5);
     235 +}
     236 +private int jjMoveStringLiteralDfa6_0(long old0, long active0)
     237 +{
     238 + if (((active0 &= old0)) == 0L)
    220 239   return jjMoveNfa_0(0, 5);
     240 + try { curChar = input_stream.readChar(); }
     241 + catch(java.io.IOException e) {
     242 + return jjMoveNfa_0(0, 5);
    221 243   }
    222  - 
    223  - private int jjMoveStringLiteralDfa6_0(long old0, long active0) {
    224  - if (((active0 &= old0)) == 0L)
    225  - return jjMoveNfa_0(0, 5);
    226  - try {
    227  - curChar = input_stream.readChar();
    228  - } catch (java.io.IOException e) {
    229  - return jjMoveNfa_0(0, 5);
    230  - }
    231  - switch (curChar) {
    232  - case 78:
    233  - return jjMoveStringLiteralDfa7_0(active0, 0x800L);
     244 + switch(curChar)
     245 + {
     246 + case 78:
     247 + return jjMoveStringLiteralDfa7_0(active0, 0x800L);
    234 248   case 83:
    235 249   if ((active0 & 0x40000L) != 0L)
    236 250   {
    skipped 4 lines
    241 255   case 110:
    242 256   return jjMoveStringLiteralDfa7_0(active0, 0x800L);
    243 257   case 115:
    244  - if ((active0 & 0x40000L) != 0L) {
     258 + if ((active0 & 0x40000L) != 0L)
     259 + {
    245 260   jjmatchedKind = 18;
    246 261   jjmatchedPos = 6;
    247 262   }
    248 263   break;
    249  - default:
    250  - break;
    251  - }
     264 + default :
     265 + break;
     266 + }
     267 + return jjMoveNfa_0(0, 6);
     268 +}
     269 +private int jjMoveStringLiteralDfa7_0(long old0, long active0)
     270 +{
     271 + if (((active0 &= old0)) == 0L)
    252 272   return jjMoveNfa_0(0, 6);
     273 + try { curChar = input_stream.readChar(); }
     274 + catch(java.io.IOException e) {
     275 + return jjMoveNfa_0(0, 6);
    253 276   }
    254  - 
    255  - private int jjMoveStringLiteralDfa7_0(long old0, long active0) {
    256  - if (((active0 &= old0)) == 0L)
    257  - return jjMoveNfa_0(0, 6);
    258  - try {
    259  - curChar = input_stream.readChar();
    260  - } catch (java.io.IOException e) {
    261  - return jjMoveNfa_0(0, 6);
    262  - }
    263  - switch (curChar) {
    264  - case 83:
    265  - if ((active0 & 0x800L) != 0L)
     277 + switch(curChar)
     278 + {
     279 + case 83:
     280 + if ((active0 & 0x800L) != 0L)
    266 281   {
    267 282   jjmatchedKind = 11;
    268 283   jjmatchedPos = 7;
    skipped 342 lines
    611 626   }
    612 627   else
    613 628   {
    614  - int hiByte = (int) (curChar >> 8);
     629 + int hiByte = (int)(curChar >> 8);
    615 630   int i1 = hiByte >> 6;
    616 631   long l1 = 1L << (hiByte & 077);
    617 632   int i2 = (curChar & 0xff) >> 6;
    618 633   long l2 = 1L << (curChar & 077);
    619 634   do
    620 635   {
    621  - switch(jjstateSet[--i]) {
     636 + switch(jjstateSet[--i])
     637 + {
    622 638   case 32:
    623 639   case 33:
    624 640   if (jjCanMove_0(hiByte, i1, i2, l1, l2))
    skipped 4 lines
    629 645   if (jjCanMove_0(hiByte, i1, i2, l1, l2))
    630 646   jjCheckNAddStates(3, 5);
    631 647   break;
    632  - default:
    633  - break;
     648 + default : break;
    634 649   }
    635 650   } while(i != startsAt);
    636 651   }
    skipped 17 lines
    654 669   if (curPos < toRet)
    655 670   for (i = toRet - Math.min(curPos, seenUpto); i-- > 0; )
    656 671   try { curChar = input_stream.readChar(); }
    657  - catch(java.io.IOException e) { throw new Error("Internal Error : Please send a bug report.");
    658  - }
     672 + catch(java.io.IOException e) { throw new Error("Internal Error : Please send a bug report."); }
    659 673   
    660  - if (jjmatchedPos < strPos) {
     674 + if (jjmatchedPos < strPos)
     675 + {
    661 676   jjmatchedKind = strKind;
    662 677   jjmatchedPos = strPos;
    663  - } else if (jjmatchedPos == strPos && jjmatchedKind > strKind)
     678 + }
     679 + else if (jjmatchedPos == strPos && jjmatchedKind > strKind)
    664 680   jjmatchedKind = strKind;
    665 681   
    666 682   return toRet;
    667 683  }
    668  - 
    669  - private final int jjStopStringLiteralDfa_1(int pos, long active0) {
    670  - switch (pos) {
    671  - default:
    672  - return -1;
    673  - }
     684 +private final int jjStopStringLiteralDfa_1(int pos, long active0)
     685 +{
     686 + switch (pos)
     687 + {
     688 + default :
     689 + return -1;
    674 690   }
    675  - 
    676  - private final int jjStartNfa_1(int pos, long active0) {
    677  - return jjMoveNfa_1(jjStopStringLiteralDfa_1(pos, active0), pos + 1);
    678  - }
    679  - 
    680  - private int jjMoveStringLiteralDfa0_1() {
    681  - switch (curChar) {
    682  - case 39:
    683  - return jjStopAtPos(0, 31);
    684  - default:
    685  - return jjMoveNfa_1(3, 0);
    686  - }
     691 +}
     692 +private final int jjStartNfa_1(int pos, long active0)
     693 +{
     694 + return jjMoveNfa_1(jjStopStringLiteralDfa_1(pos, active0), pos + 1);
     695 +}
     696 +private int jjMoveStringLiteralDfa0_1()
     697 +{
     698 + switch(curChar)
     699 + {
     700 + case 39:
     701 + return jjStopAtPos(0, 31);
     702 + default :
     703 + return jjMoveNfa_1(3, 0);
    687 704   }
    688  - 
    689  - private int jjMoveNfa_1(int startState, int curPos)
     705 +}
     706 +private int jjMoveNfa_1(int startState, int curPos)
    690 707  {
    691 708   int startsAt = 0;
    692 709   jjnewStateCnt = 3;
    skipped 67 lines
    760 777   }
    761 778   else
    762 779   {
    763  - int hiByte = (int) (curChar >> 8);
     780 + int hiByte = (int)(curChar >> 8);
    764 781   int i1 = hiByte >> 6;
    765 782   long l1 = 1L << (hiByte & 077);
    766 783   int i2 = (curChar & 0xff) >> 6;
    767 784   long l2 = 1L << (curChar & 077);
    768 785   do
    769 786   {
    770  - switch(jjstateSet[--i]) {
     787 + switch(jjstateSet[--i])
     788 + {
    771 789   case 3:
    772 790   case 2:
    773 791   case 1:
    skipped 3 lines
    777 795   kind = 30;
    778 796   jjCheckNAddTwoStates(0, 2);
    779 797   break;
    780  - default:
    781  - break;
     798 + default : break;
    782 799   }
    783 800   } while(i != startsAt);
    784 801   }
    skipped 6 lines
    791 808   ++curPos;
    792 809   if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
    793 810   return curPos;
    794  - try {
    795  - curChar = input_stream.readChar();
    796  - } catch (java.io.IOException e) {
    797  - return curPos;
    798  - }
     811 + try { curChar = input_stream.readChar(); }
     812 + catch(java.io.IOException e) { return curPos; }
    799 813   }
    800 814  }
    801  - 
    802  - private final int jjStopStringLiteralDfa_2(int pos, long active0) {
    803  - switch (pos) {
    804  - default:
    805  - return -1;
    806  - }
     815 +private final int jjStopStringLiteralDfa_2(int pos, long active0)
     816 +{
     817 + switch (pos)
     818 + {
     819 + default :
     820 + return -1;
    807 821   }
    808  - 
    809  - private final int jjStartNfa_2(int pos, long active0) {
    810  - return jjMoveNfa_2(jjStopStringLiteralDfa_2(pos, active0), pos + 1);
     822 +}
     823 +private final int jjStartNfa_2(int pos, long active0)
     824 +{
     825 + return jjMoveNfa_2(jjStopStringLiteralDfa_2(pos, active0), pos + 1);
     826 +}
     827 +private int jjMoveStringLiteralDfa0_2()
     828 +{
     829 + switch(curChar)
     830 + {
     831 + case 34:
     832 + return jjStopAtPos(0, 33);
     833 + default :
     834 + return jjMoveNfa_2(3, 0);
    811 835   }
    812  - 
    813  - private int jjMoveStringLiteralDfa0_2() {
    814  - switch (curChar) {
    815  - case 34:
    816  - return jjStopAtPos(0, 33);
    817  - default:
    818  - return jjMoveNfa_2(3, 0);
    819  - }
    820  - }
    821  - 
    822  - private int jjMoveNfa_2(int startState, int curPos)
     836 +}
     837 +private int jjMoveNfa_2(int startState, int curPos)
    823 838  {
    824 839   int startsAt = 0;
    825 840   jjnewStateCnt = 3;
    826 841   int i = 1;
    827 842   jjstateSet[0] = startState;
    828 843   int kind = 0x7fffffff;
    829  - for (;;) {
     844 + for (;;)
     845 + {
    830 846   if (++jjround == 0x7fffffff)
    831 847   ReInitRounds();
    832  - if (curChar < 64) {
     848 + if (curChar < 64)
     849 + {
    833 850   long l = 1L << curChar;
    834  - do {
    835  - switch(jjstateSet[--i]) {
     851 + do
     852 + {
     853 + switch(jjstateSet[--i])
     854 + {
    836 855   case 3:
    837 856   case 2:
    838 857   if ((0xfffffffbffffffffL & l) == 0L)
    skipped 10 lines
    849 868   default : break;
    850 869   }
    851 870   } while(i != startsAt);
    852  - } else if (curChar < 128) {
     871 + }
     872 + else if (curChar < 128)
     873 + {
    853 874   long l = 1L << (curChar & 077);
    854  - do {
    855  - switch(jjstateSet[--i]) {
     875 + do
     876 + {
     877 + switch(jjstateSet[--i])
     878 + {
    856 879   case 3:
    857  - if ((0xffffffffefffffffL & l) != 0L) {
     880 + if ((0xffffffffefffffffL & l) != 0L)
     881 + {
    858 882   if (kind > 32)
    859 883   kind = 32;
    860 884   jjCheckNAddTwoStates(0, 2);
    861  - } else if (curChar == 92)
     885 + }
     886 + else if (curChar == 92)
    862 887   jjstateSet[jjnewStateCnt++] = 1;
    863 888   break;
    864 889   case 0:
    skipped 15 lines
    880 905   default : break;
    881 906   }
    882 907   } while(i != startsAt);
    883  - } else {
    884  - int hiByte = (int) (curChar >> 8);
     908 + }
     909 + else
     910 + {
     911 + int hiByte = (int)(curChar >> 8);
    885 912   int i1 = hiByte >> 6;
    886 913   long l1 = 1L << (hiByte & 077);
    887 914   int i2 = (curChar & 0xff) >> 6;
    888 915   long l2 = 1L << (curChar & 077);
    889  - do {
    890  - switch(jjstateSet[--i]) {
     916 + do
     917 + {
     918 + switch(jjstateSet[--i])
     919 + {
    891 920   case 3:
    892 921   case 2:
    893 922   case 1:
    skipped 3 lines
    897 926   kind = 32;
    898 927   jjCheckNAddTwoStates(0, 2);
    899 928   break;
    900  - default:
    901  - break;
     929 + default : break;
    902 930   }
    903 931   } while(i != startsAt);
    904 932   }
    905  - if (kind != 0x7fffffff) {
     933 + if (kind != 0x7fffffff)
     934 + {
    906 935   jjmatchedKind = kind;
    907 936   jjmatchedPos = curPos;
    908 937   kind = 0x7fffffff;
    skipped 1 lines
    910 939   ++curPos;
    911 940   if ((i = jjnewStateCnt) == (startsAt = 3 - (jjnewStateCnt = startsAt)))
    912 941   return curPos;
    913  - try {
    914  - curChar = input_stream.readChar();
    915  - } catch (java.io.IOException e) {
    916  - return curPos;
    917  - }
     942 + try { curChar = input_stream.readChar(); }
     943 + catch(java.io.IOException e) { return curPos; }
    918 944   }
    919 945  }
    920  - 
    921  - static final int[] jjnextStates = {
    922  - 31, 33, 36, 40, 42, 43,
    923  - };
    924  - 
    925  - private static final boolean jjCanMove_0(int hiByte, int i1, int i2, long l1, long l2) {
    926  - switch (hiByte) {
    927  - case 0:
    928  - return ((jjbitVec2[i2] & l2) != 0L);
    929  - default:
    930  - if ((jjbitVec0[i1] & l1) != 0L)
    931  - return true;
    932  - return false;
    933  - }
     946 +static final int[] jjnextStates = {
     947 + 31, 33, 36, 40, 42, 43,
     948 +};
     949 +private static final boolean jjCanMove_0(int hiByte, int i1, int i2, long l1, long l2)
     950 +{
     951 + switch(hiByte)
     952 + {
     953 + case 0:
     954 + return ((jjbitVec2[i2] & l2) != 0L);
     955 + default :
     956 + if ((jjbitVec0[i1] & l1) != 0L)
     957 + return true;
     958 + return false;
    934 959   }
    935  - 
    936  - /**
    937  - * Token literal values.
    938  - */
    939  - public static final String[] jjstrLiteralImages = {
    940  - "", null, null, "\41\75", "\76", "\74", "\76\75", "\74\75", null, null, null,
    941  - null, null, null, null, null, null, null, null, "\50", "\51", null, "\56", null,
    942  - "\133", "\135", "\54", "\43", "\47", "\42", null, "\47", null, "\42", null,};
     960 +}
    943 961   
    944  - /**
    945  - * Lexer state names.
    946  - */
    947  - public static final String[] lexStateNames = {
    948  - "DEFAULT",
    949  - "SINGLE_QUOTED_STRING",
    950  - "DOUBLE_QUOTED_STRING",
    951  - };
     962 +/** Token literal values. */
     963 +public static final String[] jjstrLiteralImages = {
     964 +"", null, null, "\41\75", "\76", "\74", "\76\75", "\74\75", null, null, null,
     965 +null, null, null, null, null, null, null, null, "\50", "\51", null, "\56", null,
     966 +"\133", "\135", "\54", "\43", "\47", "\42", null, "\47", null, "\42", null, };
    952 967   
    953  - /**
    954  - * Lex State array.
    955  - */
    956  - public static final int[] jjnewLexState = {
    957  - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    958  - -1, -1, -1, 1, 2, -1, 0, -1, 0, -1,
    959  - };
    960  - static final long[] jjtoToken = {
    961  - 0x7fffffffdL,
    962  - };
    963  - static final long[] jjtoSkip = {
    964  - 0x2L,
    965  - };
    966  - protected SimpleCharStream input_stream;
    967  - private final int[] jjrounds = new int[49];
    968  - private final int[] jjstateSet = new int[98];
    969  - protected char curChar;
     968 +/** Lexer state names. */
     969 +public static final String[] lexStateNames = {
     970 + "DEFAULT",
     971 + "SINGLE_QUOTED_STRING",
     972 + "DOUBLE_QUOTED_STRING",
     973 +};
    970 974   
    971  - /**
    972  - * Constructor.
    973  - */
    974  - public FilterParserTokenManager(SimpleCharStream stream) {
    975  - if (SimpleCharStream.staticFlag)
    976  - throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer.");
    977  - input_stream = stream;
    978  - }
     975 +/** Lex State array. */
     976 +public static final int[] jjnewLexState = {
     977 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
     978 + -1, -1, -1, 1, 2, -1, 0, -1, 0, -1,
     979 +};
     980 +static final long[] jjtoToken = {
     981 + 0x7fffffffdL,
     982 +};
     983 +static final long[] jjtoSkip = {
     984 + 0x2L,
     985 +};
     986 +protected SimpleCharStream input_stream;
     987 +private final int[] jjrounds = new int[49];
     988 +private final int[] jjstateSet = new int[98];
     989 +protected char curChar;
     990 +/** Constructor. */
     991 +public FilterParserTokenManager(SimpleCharStream stream){
     992 + if (SimpleCharStream.staticFlag)
     993 + throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer.");
     994 + input_stream = stream;
     995 +}
    979 996   
    980  - /**
    981  - * Constructor.
    982  - */
    983  - public FilterParserTokenManager(SimpleCharStream stream, int lexState) {
    984  - this(stream);
    985  - SwitchTo(lexState);
    986  - }
     997 +/** Constructor. */
     998 +public FilterParserTokenManager(SimpleCharStream stream, int lexState){
     999 + this(stream);
     1000 + SwitchTo(lexState);
     1001 +}
    987 1002   
    988  - /**
    989  - * Reinitialise parser.
    990  - */
    991  - public void ReInit(SimpleCharStream stream) {
    992  - jjmatchedPos = jjnewStateCnt = 0;
    993  - curLexState = defaultLexState;
    994  - input_stream = stream;
    995  - ReInitRounds();
    996  - }
     1003 +/** Reinitialise parser. */
     1004 +public void ReInit(SimpleCharStream stream)
     1005 +{
     1006 + jjmatchedPos = jjnewStateCnt = 0;
     1007 + curLexState = defaultLexState;
     1008 + input_stream = stream;
     1009 + ReInitRounds();
     1010 +}
     1011 +private void ReInitRounds()
     1012 +{
     1013 + int i;
     1014 + jjround = 0x80000001;
     1015 + for (i = 49; i-- > 0;)
     1016 + jjrounds[i] = 0x80000000;
     1017 +}
    997 1018   
    998  - private void ReInitRounds() {
    999  - int i;
    1000  - jjround = 0x80000001;
    1001  - for (i = 49; i-- > 0; )
    1002  - jjrounds[i] = 0x80000000;
    1003  - }
     1019 +/** Reinitialise parser. */
     1020 +public void ReInit(SimpleCharStream stream, int lexState)
     1021 +{
     1022 + ReInit(stream);
     1023 + SwitchTo(lexState);
     1024 +}
    1004 1025   
    1005  - /**
    1006  - * Reinitialise parser.
    1007  - */
    1008  - public void ReInit(SimpleCharStream stream, int lexState) {
    1009  - ReInit(stream);
    1010  - SwitchTo(lexState);
    1011  - }
     1026 +/** Switch to specified lex state. */
     1027 +public void SwitchTo(int lexState)
     1028 +{
     1029 + if (lexState >= 3 || lexState < 0)
     1030 + throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
     1031 + else
     1032 + curLexState = lexState;
     1033 +}
    1012 1034   
    1013  - /**
    1014  - * Switch to specified lex state.
    1015  - */
    1016  - public void SwitchTo(int lexState) {
    1017  - if (lexState >= 3 || lexState < 0)
    1018  - throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE);
    1019  - else
    1020  - curLexState = lexState;
    1021  - }
    1022  - 
    1023  - protected Token jjFillToken() {
    1024  - final Token t;
    1025  - final String curTokenImage;
    1026  - final int beginLine;
    1027  - final int endLine;
    1028  - final int beginColumn;
    1029  - final int endColumn;
    1030  - String im = jjstrLiteralImages[jjmatchedKind];
     1035 +protected Token jjFillToken()
     1036 +{
     1037 + final Token t;
     1038 + final String curTokenImage;
     1039 + final int beginLine;
     1040 + final int endLine;
     1041 + final int beginColumn;
     1042 + final int endColumn;
     1043 + String im = jjstrLiteralImages[jjmatchedKind];
    1031 1044   curTokenImage = (im == null) ? input_stream.GetImage() : im;
    1032 1045   beginLine = input_stream.getBeginLine();
    1033 1046   beginColumn = input_stream.getBeginColumn();
    skipped 22 lines
    1056 1069   Token matchedToken;
    1057 1070   int curPos = 0;
    1058 1071   
    1059  - EOFLoop:
    1060  - for (; ; ) {
    1061  - try {
    1062  - curChar = input_stream.BeginToken();
    1063  - } catch (java.io.IOException e)
     1072 + EOFLoop :
     1073 + for (;;)
     1074 + {
     1075 + try
     1076 + {
     1077 + curChar = input_stream.BeginToken();
     1078 + }
     1079 + catch(java.io.IOException e)
    1064 1080   {
    1065 1081   jjmatchedKind = 0;
    1066 1082   matchedToken = jjFillToken();
    skipped 103 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/filter/savedfilter/SavedFilter.java
    1 1  package com.nccgroup.loggerplusplus.filter.savedfilter;
    2 2   
    3  -import com.nccgroup.loggerplusplus.filter.logfilter.LogFilter;
     3 +import com.nccgroup.loggerplusplus.filter.FilterExpression;
     4 +import com.nccgroup.loggerplusplus.filter.FilterRule;
    4 5  import com.nccgroup.loggerplusplus.filter.parser.ParseException;
    5  -import com.nccgroup.loggerplusplus.filterlibrary.FilterLibraryController;
    6 6   
    7 7  /**
    8 8   * Created by corey on 19/07/17.
    9 9   */
    10  -public class SavedFilter {
    11  - private String name;
    12  - private LogFilter filter;
    13  - private String filterString;
    14  - 
    15  - public SavedFilter(FilterLibraryController filterLibraryController, String name, String filterString) throws ParseException {
    16  - this.name = name.replaceAll("[^a-zA-Z0-9_.]", "_");
    17  - this.setFilter(new LogFilter(filterLibraryController, filterString));
    18  - }
     10 +public class SavedFilter extends FilterRule {
    19 11   
    20  - public LogFilter getFilter() {
    21  - return filter;
    22  - }
    23  - 
    24  - public void setFilter(LogFilter filter) {
    25  - this.filter = filter;
    26  - if(filter != null)
    27  - this.filterString = filter.toString();
     12 + public SavedFilter(String name, String filterString) {
     13 + super(name.replaceAll("[^a-zA-Z0-9_.]", "_"));
     14 + this.trySetFilter(filterString);
    28 15   }
    29 16   
    30  - public String getName() {
    31  - return name;
     17 + public SavedFilter(String name, FilterExpression filterExpression){
     18 + super(name, filterExpression);
    32 19   }
    33 20   
     21 + @Override
    34 22   public void setName(String name) {
    35 23   name = name.replaceAll("[^a-zA-Z0-9_.]", "_");
    36  - this.name = name;
    37  - }
    38  - 
    39  - public String getFilterString() {
    40  - return filterString;
    41  - }
    42  - 
    43  - public void setFilterString(String filterString) {
    44  - this.filterString = filterString;
     24 + super.setName(name);
    45 25   }
    46 26   
    47 27   @Override
    48 28   public boolean equals(Object o) {
    49 29   if(o instanceof SavedFilter){
    50 30   SavedFilter other = (SavedFilter) o;
    51  - return other.name.equals(name) && other.filterString.equals(filterString);
     31 + return other.getName().equals(getName()) && other.getFilterString().equals(getFilterString());
    52 32   }else{
    53 33   return super.equals(o);
    54 34   }
    skipped 1 lines
    56 36   
    57 37   @Override
    58 38   public String toString() {
    59  - return "SavedFilter[" + this.name + ", " + (this.filter == null ? this.filterString : this.filter) + "]";
     39 + return "SavedFilter[" + this.getName() + ", " + (this.getFilterExpression() == null ? this.getFilterString() : this.getFilterExpression()) + "]";
    60 40   }
    61 41  }
    62 42   
  • ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/filter/tag/Tag.java
    1 1  package com.nccgroup.loggerplusplus.filter.tag;
    2 2   
    3  -import com.nccgroup.loggerplusplus.filter.logfilter.LogFilter;
     3 +import com.nccgroup.loggerplusplus.filter.ColorizingFilterRule;
     4 +import com.nccgroup.loggerplusplus.filter.FilterExpression;
     5 +import com.nccgroup.loggerplusplus.filter.logfilter.LogTableFilter;
    4 6  import com.nccgroup.loggerplusplus.filter.parser.ParseException;
    5 7  import com.nccgroup.loggerplusplus.filterlibrary.FilterLibraryController;
     8 +import lombok.Getter;
    6 9   
    7 10  import java.awt.*;
    8 11  import java.util.UUID;
    skipped 1 lines
    10 13  /**
    11 14   * Created by corey on 19/07/17.
    12 15   */
    13  -public class Tag implements Comparable<Tag> {
    14  - private UUID uid;
    15  - private String name;
    16  - private LogFilter filter;
    17  - private String filterString;
    18  - private Color backgroundColor;
    19  - private Color foregroundColor;
    20  - private boolean enabled;
    21  - private boolean modified;
    22  - private boolean shouldRetest;
    23  - private short priority;
     16 +public class Tag extends ColorizingFilterRule implements Comparable<Tag> {
    24 17   
    25  - public Tag() {
    26  - this.uid = UUID.randomUUID();
    27  - this.enabled = true;
    28  - this.shouldRetest = true;
    29  - }
     18 + @Getter
     19 + private boolean shouldRetest = true;
    30 20   
    31  - public Tag(String title, LogFilter filter) {
    32  - this();
    33  - this.name = title;
    34  - this.setFilter(filter);
     21 + public Tag(){
     22 + super("", "");
    35 23   }
    36 24   
    37  - public Tag(FilterLibraryController filterLibraryController, String title, String filterString) throws ParseException {
    38  - this(title, new LogFilter(filterLibraryController, filterString));
    39  - }
    40  - 
    41  - public Tag(String title, LogFilter filter, Color foreground, Color background) {
    42  - this(title, filter);
    43  - this.foregroundColor = foreground;
    44  - this.backgroundColor = background;
    45  - }
    46  - 
    47  - public UUID getUUID() {
    48  - return uid;
    49  - }
    50  - 
    51  - public void setBackgroundColor(Color backgroundColor) {
    52  - this.backgroundColor = backgroundColor;
    53  - this.modified = true;
     25 + public Tag(String title, String filterString) {
     26 + super(title, filterString);
    54 27   }
    55 28   
    56  - public Color getBackgroundColor() {
    57  - return backgroundColor;
    58  - }
    59  - 
    60  - public Color getForegroundColor() {
    61  - return foregroundColor;
    62  - }
    63  - 
    64  - public void setForegroundColor(Color foregroundColor) {
    65  - this.foregroundColor = foregroundColor;
    66  - modified = true;
     29 + public Tag(String title, FilterExpression filterExpression) {
     30 + super(title, filterExpression);
    67 31   }
    68 32   
    69  - public LogFilter getFilter() {
    70  - return filter;
     33 + @Override
     34 + public boolean trySetFilter(String filterString){
     35 + boolean success = super.trySetFilter(filterString);
     36 + if(success) shouldRetest = true;
     37 + return success;
    71 38   }
    72 39   
    73  - public void setFilter(LogFilter filter) {
    74  - this.filter = filter;
    75  - if (filter != null)
    76  - this.filterString = filter.toString();
    77  - modified = true;
     40 + @Override
     41 + public void setFilter(FilterExpression filter) {
     42 + super.setFilter(filter);
    78 43   shouldRetest = true;
    79 44   }
    80 45   
    81  - public String getName() {
    82  - return name;
    83  - }
    84  - 
    85  - public void setName(String name) {
    86  - this.name = name;
    87  - }
    88  - 
    89  - public boolean isEnabled() {
    90  - return enabled;
    91  - }
    92  - 
     46 + @Override
    93 47   public void setEnabled(boolean enabled) {
    94  - this.enabled = enabled;
    95  - modified = true;
     48 + super.setEnabled(enabled);
    96 49   shouldRetest = true;
    97 50   }
    98 51   
    99  - public String getFilterString() {
    100  - return filterString;
    101  - }
    102  - 
    103  - public void setFilterString(String filterString) {
    104  - this.filterString = filterString;
    105  - }
    106  - 
    107  - public boolean equals(Object obj) {
    108  - if (obj instanceof Tag) {
    109  - return ((Tag) obj).getUUID().equals(this.uid);
    110  - } else {
    111  - return super.equals(obj);
    112  - }
    113  - }
    114  - 
    115  - public boolean isModified() {
    116  - return modified;
    117  - }
    118  - 
    119  - public void setModified(boolean modified) {
    120  - this.modified = modified;
    121  - }
    122  - 
     52 + @Override
    123 53   public void setPriority(short priority) {
    124  - this.priority = priority;
    125  - this.modified = true;
    126  - }
    127  - 
    128  - public short getPriority() {
    129  - return priority;
     54 + super.setPriority(priority);
     55 + shouldRetest = true;
    130 56   }
    131 57   
    132 58   @Override
    133 59   public int compareTo(Tag tag) {
    134  - return ((Comparable) this.priority).compareTo(tag.getPriority());
     60 + return ((Comparable) this.getPriority()).compareTo(tag.getPriority());
    135 61   }
    136 62   
    137 63   public boolean shouldRetest() {
    skipped 2 lines
    140 66   
    141 67   @Override
    142 68   public String toString() {
    143  - return "ColorFilter[" + (this.filter != null ? this.filter.toString() : "") + "]";
     69 + return this.getName();
    144 70   }
    145 71  }
    146 72   
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/filterlibrary/FilterLibraryController.java
    1 1  package com.nccgroup.loggerplusplus.filterlibrary;
    2 2   
    3 3  import com.coreyd97.BurpExtenderUtilities.Preferences;
    4  -import com.nccgroup.loggerplusplus.LoggerPlusPlus;
    5  -import com.nccgroup.loggerplusplus.filter.colorfilter.ColorFilter;
     4 +import com.nccgroup.loggerplusplus.filter.FilterExpression;
     5 +import com.nccgroup.loggerplusplus.filter.colorfilter.TableColorRule;
    6 6  import com.nccgroup.loggerplusplus.filter.colorfilter.ColorFilterListener;
    7  -import com.nccgroup.loggerplusplus.filter.logfilter.LogFilter;
     7 +import com.nccgroup.loggerplusplus.filter.logfilter.LogTableFilter;
    8 8  import com.nccgroup.loggerplusplus.filter.savedfilter.SavedFilter;
    9 9  import com.nccgroup.loggerplusplus.filter.tag.Tag;
    10 10  import com.nccgroup.loggerplusplus.filter.tag.TagListener;
    11 11  import com.nccgroup.loggerplusplus.preferences.PreferencesController;
    12 12  import com.nccgroup.loggerplusplus.util.Globals;
    13  -import org.apache.logging.log4j.LogManager;
    14  -import org.apache.logging.log4j.Logger;
     13 +import lombok.extern.log4j.Log4j2;
    15 14   
    16 15  import java.awt.*;
    17 16  import java.util.ArrayList;
    18 17  import java.util.HashMap;
    19 18  import java.util.UUID;
    20 19   
     20 +@Log4j2
    21 21  public class FilterLibraryController {
    22 22   
    23  - private final LoggerPlusPlus loggerPlusPlus;
    24 23   private final Preferences preferences;
    25 24   private final FilterLibraryPanel panel;
    26 25   private final ArrayList<FilterLibraryListener> listeners;
    27 26   private final ArrayList<SavedFilter> savedFilters;
    28  - private final HashMap<UUID, ColorFilter> colorFilters;
     27 + private final HashMap<UUID, TableColorRule> colorFilters;
    29 28   private final ArrayList<ColorFilterListener> colorFilterListeners;
    30 29   private final HashMap<UUID, Tag> tagFilters;
    31 30   private final ArrayList<TagListener> tagListeners;
    32 31   
    33  - Logger logger = LogManager.getRootLogger();
    34  - 
    35  - public FilterLibraryController(LoggerPlusPlus loggerPlusPlus, PreferencesController preferencesController) {
    36  - this.loggerPlusPlus = loggerPlusPlus;
     32 + public FilterLibraryController(PreferencesController preferencesController) {
    37 33   this.preferences = preferencesController.getPreferences();
    38 34   this.listeners = new ArrayList<>();
    39 35   this.colorFilterListeners = new ArrayList<>();
    skipped 4 lines
    44 40   this.panel = new FilterLibraryPanel(this);
    45 41   }
    46 42   
    47  - public LoggerPlusPlus getLoggerPlusPlus() {
    48  - return loggerPlusPlus;
    49  - }
    50  - 
    51 43   public FilterLibraryPanel getFilterLibraryPanel() {
    52 44   return panel;
    53 45   }
    54 46   
    55  - public ArrayList<SavedFilter> getSavedFilters(){
     47 + public ArrayList<SavedFilter> getFilterSnippets(){
    56 48   return this.savedFilters;
    57 49   }
    58 50   
    skipped 41 lines
    100 92   this.listeners.remove(listener);
    101 93   }
    102 94   
    103  - public HashMap<UUID, ColorFilter> getColorFilters() {
     95 + public HashMap<UUID, TableColorRule> getColorFilters() {
    104 96   return colorFilters;
    105 97   }
    106 98   
    107  - public void addColorFilter(String title, LogFilter filter){
     99 + public void addColorFilter(String title, FilterExpression filter){
    108 100   this.addColorFilter(title, filter, Color.BLACK, Color.WHITE);
    109 101   }
    110 102   
    111  - public void addColorFilter(String title, LogFilter filter, Color foreground, Color background){
    112  - this.addColorFilter(new ColorFilter(title, filter, foreground, background));
     103 + public void addColorFilter(String title, FilterExpression filter, Color foreground, Color background){
     104 + this.addColorFilter(new TableColorRule(title, filter));
    113 105   }
    114 106   
    115  - public void addColorFilter(ColorFilter colorFilter){
    116  - this.colorFilters.put(colorFilter.getUUID(), colorFilter);
     107 + public void addColorFilter(TableColorRule tableColorRule){
     108 + this.colorFilters.put(tableColorRule.getUuid(), tableColorRule);
    117 109   
    118 110   for (ColorFilterListener colorFilterListener : this.colorFilterListeners) {
    119 111   try {
    120  - colorFilterListener.onColorFilterAdd(colorFilter);
     112 + colorFilterListener.onColorFilterAdd(tableColorRule);
    121 113   } catch (Exception e) {
    122  - logger.error(e);
     114 + log.error(e);
    123 115   }
    124 116   }
    125 117   saveColorFilters();
    126 118   }
    127 119   
    128  - public void removeColorFilter(ColorFilter colorFilter){
     120 + public void removeColorFilter(TableColorRule tableColorRule){
    129 121   synchronized (this.colorFilters){
    130  - this.colorFilters.remove(colorFilter.getUUID());
     122 + this.colorFilters.remove(tableColorRule.getUuid());
    131 123   }
    132 124   for (ColorFilterListener listener : this.colorFilterListeners) {
    133 125   try{
    134  - listener.onColorFilterRemove(colorFilter);
     126 + listener.onColorFilterRemove(tableColorRule);
    135 127   }catch (Exception e){
    136  - logger.error(e);
     128 + log.error(e);
    137 129   }
    138 130   }
    139 131   saveColorFilters();
    140 132   }
    141 133   
    142 134   //Called when a filter is modified.
    143  - public void updateColorFilter(ColorFilter colorFilter){
     135 + public void updateColorFilter(TableColorRule tableColorRule){
    144 136   for (ColorFilterListener listener : this.colorFilterListeners) {
    145 137   try{
    146  - listener.onColorFilterChange(colorFilter);
     138 + listener.onColorFilterChange(tableColorRule);
    147 139   }catch (Exception e){
    148  - logger.error(e);
     140 + log.error(e);
    149 141   }
    150 142   }
    151 143   saveColorFilters();
    skipped 16 lines
    168 160   }
    169 161   
    170 162   public void addTag(Tag tag) {
    171  - this.tagFilters.put(tag.getUUID(), tag);
     163 + this.tagFilters.put(tag.getUuid(), tag);
    172 164   
    173 165   for (TagListener listener : this.tagListeners) {
    174 166   try {
    175 167   listener.onTagAdd(tag);
    176 168   } catch (Exception error) {
    177  - logger.error(error);
     169 + log.error(error);
    178 170   }
    179 171   }
    180 172   saveTags();
    skipped 1 lines
    182 174   
    183 175   public void removeTag(Tag tag) {
    184 176   synchronized (this.tagFilters) {
    185  - this.tagFilters.remove(tag.getUUID());
     177 + this.tagFilters.remove(tag.getUuid());
    186 178   }
    187 179   for (TagListener listener : this.tagListeners) {
    188 180   try {
    189 181   listener.onTagRemove(tag);
    190 182   } catch (Exception error) {
    191  - logger.error(error);
     183 + log.error(error);
    192 184   }
    193 185   }
    194 186   saveTags();
    skipped 5 lines
    200 192   try {
    201 193   listener.onTagChange(tag);
    202 194   } catch (Exception e) {
    203  - logger.error(e);
     195 + log.error(e);
    204 196   }
    205 197   }
    206 198   saveTags();
    skipped 11 lines
    218 210   this.tagListeners.remove(listener);
    219 211   }
    220 212   
     213 + public void propagateChangesToSnippetUsers(SavedFilter savedFilter) {
     214 + String snippet = savedFilter.getName();
     215 + for (TableColorRule tableColorRule : this.getColorFilters().values()) {
     216 + if(tableColorRule.getFilterExpression().getSnippetDependencies().contains(snippet)){
     217 + updateColorFilter(tableColorRule);
     218 + }
     219 + }
     220 + 
     221 + for (Tag tag : this.getTags().values()) {
     222 + if(tag.getFilterExpression().getSnippetDependencies().contains(snippet)){
     223 + updateTag(tag);
     224 + }
     225 + }
     226 + }
    221 227  }
    222 228   
  • ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/filterlibrary/FilterLibraryPanel.java
    1 1  package com.nccgroup.loggerplusplus.filterlibrary;
    2 2   
    3  -import com.nccgroup.loggerplusplus.LoggerPlusPlus;
    4 3  import com.nccgroup.loggerplusplus.filter.parser.ParseException;
    5 4  import com.nccgroup.loggerplusplus.filter.savedfilter.SavedFilter;
    6 5  import com.nccgroup.loggerplusplus.util.userinterface.renderer.ButtonRenderer;
    skipped 42 lines
    49 48   JButton addFilterButton = new JButton("Add Snippet");
    50 49   addFilterButton.setPreferredSize(new Dimension(0, 75));
    51 50   addFilterButton.addActionListener(actionEvent -> {
    52  - try {
    53  - libraryController.addFilter(new SavedFilter(libraryController,
    54  - "Unnamed", "Response.body CONTAINS \"Example\""));
    55  - } catch (ParseException e) {
    56  - e.printStackTrace();
    57  - }
     51 + libraryController.addFilter(new SavedFilter("Unnamed", "Response.body CONTAINS \"Example\""));
    58 52   });
    59 53   JButton removeSelectedButton = new JButton("Remove Selected");
    60 54   removeSelectedButton.setMinimumSize(new Dimension(0, 75));
    61 55   removeSelectedButton.addActionListener(actionEvent -> {
    62 56   int selectedRow = libraryTable.getSelectedRow();
    63 57   if(selectedRow == -1) return;
    64  - SavedFilter filter = libraryController.getSavedFilters().get(selectedRow);
     58 + SavedFilter filter = libraryController.getFilterSnippets().get(selectedRow);
    65 59   libraryController.removeFilter(filter);
    66 60   });
    67 61   controlPanel.add(addFilterButton);
    skipped 8 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/filterlibrary/FilterLibraryTableModel.java
    1 1  package com.nccgroup.loggerplusplus.filterlibrary;
    2 2   
    3  -import burp.BurpExtender;
    4 3  import com.nccgroup.loggerplusplus.LoggerPlusPlus;
    5  -import com.nccgroup.loggerplusplus.filter.logfilter.LogFilter;
    6 4  import com.nccgroup.loggerplusplus.filter.parser.ParseException;
    7 5  import com.nccgroup.loggerplusplus.filter.savedfilter.SavedFilter;
    8 6  import com.nccgroup.loggerplusplus.util.userinterface.dialog.ColorFilterDialog;
    skipped 18 lines
    27 25   
    28 26   @Override
    29 27   public int getRowCount() {
    30  - return controller.getSavedFilters().size();
     28 + return controller.getFilterSnippets().size();
    31 29   }
    32 30   
    33 31   @Override
    skipped 3 lines
    37 35   
    38 36   @Override
    39 37   public Object getValueAt(int row, int column) {
    40  - if(row >= controller.getSavedFilters().size()) return null;
    41  - SavedFilter savedFilter = controller.getSavedFilters().get(row);
     38 + if(row >= controller.getFilterSnippets().size()) return null;
     39 + SavedFilter savedFilter = controller.getFilterSnippets().get(row);
    42 40   switch (column){
    43 41   case 0: return savedFilter.getName();
    44 42   case 1: {
    45  - if(savedFilter.getFilter() == null) return savedFilter.getFilterString();
    46  - else return savedFilter.getFilter();
     43 + return savedFilter.getFilterExpression() == null ? savedFilter.getFilterString() : savedFilter.getFilterExpression();
    47 44   }
    48 45   case 2: return btnApplyFilter;
    49 46   case 3: return btnSetColorFilter;
    skipped 13 lines
    63 60   
    64 61   @Override
    65 62   public void setValueAt(Object value, int row, int column) {
    66  - SavedFilter savedFilter = controller.getSavedFilters().get(row);
     63 + SavedFilter savedFilter = controller.getFilterSnippets().get(row);
    67 64   if(savedFilter == null) return;
    68 65   if(column == 0) {
    69 66   savedFilter.setName((String) value);
    skipped 4 lines
    74 71   }
    75 72   if(column == 1){
    76 73   try{
    77  - savedFilter.setFilter(new LogFilter(LoggerPlusPlus.instance.getLibraryController(), (String) value));
     74 + savedFilter.parseAndSetFilter((String) value);
     75 + controller.propagateChangesToSnippetUsers(savedFilter);
    78 76   }catch (ParseException e){
    79 77   //Not a valid filter...
    80  - savedFilter.setFilterString((String) value);
    81  - savedFilter.setFilter(null);
    82 78   MoreHelp.showLargeOutputDialog("Filter Exception", "<html>" + e.getMessage().replaceAll("\n", "<br>") + "</html>");
    83 79  // JOptionPane.showMessageDialog(LoggerPlusPlus.instance.getMainViewController().getUiComponent(), "<html><body style=\"max-height: 400px; max-width: 400px;\">" + e.getMessage().replaceAll("\n", "<br>") + "</html>", "Filter Exception", JOptionPane.ERROR_MESSAGE);
    84 80   }
    skipped 2 lines
    87 83   }
    88 84   
    89 85   public void onClick(int row, int col) {
    90  - if(row < 0 || row >= controller.getSavedFilters().size()) return;
    91  - SavedFilter savedFilter = controller.getSavedFilters().get(row);
     86 + if(row < 0 || row >= controller.getFilterSnippets().size()) return;
     87 + SavedFilter savedFilter = controller.getFilterSnippets().get(row);
    92 88   if(col == 2){
    93  - controller.getLoggerPlusPlus().getLogViewController().getLogFilterController().setFilter(savedFilter.getFilterString());
    94  - controller.getLoggerPlusPlus().getMainViewController().getTabbedPanel().setSelectedIndex(0);
     89 + LoggerPlusPlus.instance.getLogViewController().getLogFilterController().setFilter(savedFilter.getFilterString());
     90 + LoggerPlusPlus.instance.getMainViewController().getTabbedPanel().setSelectedIndex(0);
    95 91   return;
    96 92   }
    97 93   if(col == 3){
    98  - controller.addColorFilter(savedFilter.getName(), savedFilter.getFilter());
     94 + controller.addColorFilter(savedFilter.getName(), savedFilter.getFilterExpression());
    99 95   ColorFilterDialog dialog = new ColorFilterDialog(LoggerPlusPlus.instance.getLibraryController());
    100 96   dialog.setVisible(true);
    101 97   }
    skipped 25 lines
  • ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/grepper/GrepResultsTable.java
    1 1  package com.nccgroup.loggerplusplus.grepper;
    2 2   
     3 +import com.nccgroup.loggerplusplus.LoggerPlusPlus;
    3 4  import com.nccgroup.loggerplusplus.logview.logtable.LogTable;
    4 5  import org.jdesktop.swingx.JXTree;
    5 6  import org.jdesktop.swingx.JXTreeTable;
    skipped 45 lines
    51 52   public void actionPerformed(ActionEvent actionEvent) {
    52 53   LogTable table = controller.getLogTableController().getLogTable();
    53 54   table.changeSelection(table.convertRowIndexToView(index), 1, false, false);
    54  - controller.getLoggerPlusPlus().getMainViewController().getTabbedPanel().setSelectedIndex(0);
     55 + LoggerPlusPlus.instance.getMainViewController().getTabbedPanel().setSelectedIndex(0);
    55 56   }
    56 57   });
    57 58   menu.add(viewInLogs);
    skipped 167 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/grepper/GrepperController.java
    1 1  package com.nccgroup.loggerplusplus.grepper;
    2 2   
    3  -import burp.IHttpRequestResponse;
    4  -import burp.IHttpRequestResponseWithMarkers;
     3 +import burp.api.montoya.core.Marker;
     4 +import burp.api.montoya.core.Range;
     5 +import burp.api.montoya.http.message.HttpRequestResponse;
    5 6  import com.coreyd97.BurpExtenderUtilities.Preferences;
    6 7  import com.nccgroup.loggerplusplus.LoggerPlusPlus;
    7 8  import com.nccgroup.loggerplusplus.logentry.LogEntry;
    skipped 12 lines
    20 21   
    21 22  public class GrepperController {
    22 23   
    23  - private final LoggerPlusPlus loggerPlusPlus;
    24 24   private final LogTableController logTableController;
    25 25   private final Preferences preferences;
    26 26   private final GrepperPanel grepPanel;
    skipped 2 lines
    29 29   
    30 30   private ExecutorService searchExecutor;
    31 31   
    32  - public GrepperController(LoggerPlusPlus loggerPlusPlus, LogTableController logTableController, PreferencesController preferencesController){
    33  - this.loggerPlusPlus = loggerPlusPlus;
     32 + public GrepperController(LogTableController logTableController, PreferencesController preferencesController){
    34 33   this.logTableController = logTableController;
    35 34   this.preferences = preferencesController.getPreferences();
    36 35   this.listeners = new ArrayList<>();
    skipped 1 lines
    38 37   this.grepPanel = new GrepperPanel(this, preferences);
    39 38   }
    40 39   
    41  - public LoggerPlusPlus getLoggerPlusPlus() {
    42  - return loggerPlusPlus;
    43  - }
    44  - 
    45 40   public LogTableController getLogTableController() {
    46 41   return logTableController;
    47 42   }
    skipped 16 lines
    64 59   }
    65 60   }
    66 61   
    67  - public IHttpRequestResponseWithMarkers addMarkers(IHttpRequestResponse requestResponse, List<GrepResults.Match> matches) {
    68  - List<int[]> requestMarkers = new ArrayList<>(), responseMarkers = new ArrayList<>();
     62 + public HttpRequestResponse addMarkers(HttpRequestResponse requestResponse, List<GrepResults.Match> matches) {
     63 + List<Marker> requestMarkers = new ArrayList<>(), responseMarkers = new ArrayList<>();
    69 64   for (GrepResults.Match match : matches) {
    70  - int[] marker = new int[]{match.startIndex, match.endIndex};
     65 + Marker marker = Marker.marker(match.startIndex, match.endIndex);
    71 66   if (match.isRequest) requestMarkers.add(marker);
    72 67   else responseMarkers.add(marker);
    73 68   }
    74 69   
    75  - return LoggerPlusPlus.callbacks.applyMarkers(requestResponse, requestMarkers, responseMarkers);
     70 + return requestResponse.withRequestMarkers(requestMarkers).withResponseMarkers(responseMarkers);
    76 71   }
    77 72   
    78 73   public void beginSearch(final Pattern pattern, final boolean inScopeOnly, final boolean searchRequests, final boolean searchResponses) {
    skipped 1 lines
    80 75   this.searchExecutor = Executors.newFixedThreadPool(searchThreads, new NamedThreadFactory("LPP-Grepper"));
    81 76   
    82 77   new Thread(() -> {
    83  - ArrayList<LogEntry> logEntries = new ArrayList<>(loggerPlusPlus.getLogViewController().getLogTableController().getLogTableModel().getData());
     78 + ArrayList<LogEntry> logEntries = new ArrayList<>(LoggerPlusPlus.instance.getLogViewController().getLogTableController().getLogTableModel().getData());
    84 79   remainingEntries.getAndSet(logEntries.size());
    85 80   
    86 81   this.listeners.forEach(listener -> {
    skipped 10 lines
    97 92   GrepResults grepResults = null;
    98 93   if (entry != null) {
    99 94   grepResults = new GrepResults(entry);
    100  - if (entry.getRequest() != null && searchRequests) {
    101  - processMatches(grepResults, pattern, entry.getRequest(), true);
     95 + if (entry.getRequestBytes() != null && searchRequests) {
     96 + processMatches(grepResults, pattern, entry.getRequestBytes(), true);
    102 97   }
    103  - if (entry.getResponse() != null && searchResponses) {
    104  - processMatches(grepResults, pattern, entry.getResponse(), false);
     98 + if (entry.getResponseBytes() != null && searchResponses) {
     99 + processMatches(grepResults, pattern, entry.getResponseBytes(), false);
    105 100   }
    106 101   }
    107 102   return grepResults;
    skipped 20 lines
    128 123   return () -> {
    129 124   if (Thread.currentThread().isInterrupted()) return;
    130 125   GrepResults grepResults = null;
    131  - if (!inScopeOnly || LoggerPlusPlus.callbacks.isInScope(logEntry.getUrl())) {
     126 + if (!inScopeOnly || LoggerPlusPlus.isUrlInScope(logEntry.getUrlString())) {
    132 127   grepResults = processEntry(logEntry, pattern, searchRequests, searchResponses);
    133 128   }
    134 129   for (GrepperListener listener : this.listeners) {
    skipped 60 lines
  • ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/grepper/GrepperPanel.java
    skipped 2 lines
    3 3  import com.coreyd97.BurpExtenderUtilities.HistoryField;
    4 4  import com.coreyd97.BurpExtenderUtilities.PanelBuilder;
    5 5  import com.coreyd97.BurpExtenderUtilities.Preferences;
     6 +import com.nccgroup.loggerplusplus.LoggerPlusPlus;
    6 7  import com.nccgroup.loggerplusplus.logentry.LogEntry;
    7 8  import com.nccgroup.loggerplusplus.logview.entryviewer.RequestViewerController;
    8 9  import com.nccgroup.loggerplusplus.util.Globals;
    skipped 63 lines
    72 73   });
    73 74   
    74 75   this.grepResultsTable = new GrepResultsTable(controller);
    75  - this.requestViewerController = new RequestViewerController(preferences, false, false);
     76 + this.requestViewerController = new RequestViewerController(preferences);
    76 77   
    77 78   grepResultsTable.addTreeSelectionListener(treeSelectionEvent -> {
    78 79   TreePath selectedPath = treeSelectionEvent.getPath();
    skipped 58 lines
    137 138   try {
    138 139   pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);
    139 140   } catch (PatternSyntaxException e) {
    140  - JOptionPane.showMessageDialog(JOptionPane.getFrameForComponent(controller.getLoggerPlusPlus().getMainViewController().getUiComponent()), "Pattern Syntax Invalid", "Invalid Pattern", JOptionPane.ERROR_MESSAGE);
     141 + JOptionPane.showMessageDialog(JOptionPane.getFrameForComponent(LoggerPlusPlus.instance.getMainViewController().getUiComponent()), "Pattern Syntax Invalid", "Invalid Pattern", JOptionPane.ERROR_MESSAGE);
    141 142   return;
    142 143   }
    143 144   
    skipped 58 lines
  • ■ ■ ■ ■ ■ ■
    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 12 lines
    13 13   
    14 14  package com.nccgroup.loggerplusplus.imports;
    15 15   
    16  -import burp.IBurpExtenderCallbacks;
    17  -import burp.IExtensionHelpers;
    18  -import burp.IHttpRequestResponse;
     16 +import burp.api.montoya.core.ByteArray;
     17 +import burp.api.montoya.core.ToolType;
     18 +import burp.api.montoya.http.HttpService;
     19 +import burp.api.montoya.http.message.HttpRequestResponse;
     20 +import burp.api.montoya.http.message.requests.HttpRequest;
     21 +import burp.api.montoya.http.message.responses.HttpResponse;
     22 +import burp.api.montoya.utilities.Base64DecodingOptions;
     23 +import burp.api.montoya.utilities.Base64Utils;
    19 24  import com.nccgroup.loggerplusplus.LoggerPlusPlus;
    20 25  import com.nccgroup.loggerplusplus.logview.processor.EntryImportWorker;
     26 +import lombok.extern.log4j.Log4j2;
     27 +import org.apache.logging.log4j.util.Base64Util;
    21 28   
    22 29  import javax.swing.*;
    23 30  import java.io.BufferedReader;
    skipped 2 lines
    26 33  import java.io.IOException;
    27 34  import java.net.URL;
    28 35  import java.util.ArrayList;
     36 +import java.util.Base64;
    29 37  import java.util.Iterator;
    30 38   
     39 +@Log4j2
    31 40  public class LoggerImport {
    32 41   
    33 42   public static String getLoadFile() {
    skipped 16 lines
    50 59   try {
    51 60   reader = new BufferedReader(new FileReader(filename));
    52 61   } catch (FileNotFoundException e) {
    53  - LoggerPlusPlus.callbacks.printError("LoggerImport-readFile: Error Opening File " + filename);
     62 + log.error("LoggerImport-readFile: Error Opening File " + filename);
    54 63   return new ArrayList<String>();
    55 64   }
    56 65   try {
    skipped 2 lines
    59 68   lines.add(line);
    60 69   }
    61 70   } catch (IOException e) {
    62  - LoggerPlusPlus.callbacks.printError("LoggerImport-readFile: Error Reading Line");
     71 + log.error("LoggerImport-readFile: Error Reading Line");
    63 72   return new ArrayList<String>();
    64 73   }
    65 74   
    66 75   return lines;
    67 76   }
    68 77   
    69  - public static ArrayList<IHttpRequestResponse> importWStalker() {
     78 + public static ArrayList<HttpRequestResponse> importWStalker() {
    70 79   ArrayList<String> lines;
    71  - ArrayList<IHttpRequestResponse> requests = new ArrayList<>();
    72  - IExtensionHelpers helpers = LoggerPlusPlus.callbacks.getHelpers();
     80 + ArrayList<HttpRequestResponse> requests = new ArrayList<>();
    73 81  
    74 82   String filename = getLoadFile();
    75 83   if ( filename.length() == 0 ) { // exit if no file selected
    skipped 8 lines
    84 92   String line = i.next();
    85 93   String[] v = line.split(","); // Format: "base64(request),base64(response),url"
    86 94   
    87  - byte[] request = helpers.base64Decode(v[0]);
    88  - byte[] response = helpers.base64Decode(v[1]);
    89 95   String url = v[3];
     96 + Base64Utils b64Decoder = LoggerPlusPlus.montoya.utilities().base64Utils();
     97 + HttpService httpService = HttpService.httpService(url);
     98 + HttpRequest httpRequest = HttpRequest.httpRequest(httpService, b64Decoder.decode(v[0], Base64DecodingOptions.URL));
     99 + HttpResponse httpResponse = HttpResponse.httpResponse(b64Decoder.decode(v[1], Base64DecodingOptions.URL));
     100 + HttpRequestResponse requestResponse = HttpRequestResponse.httpRequestResponse(httpRequest, httpResponse);
    90 101   
    91  - ImportRequestResponse x = new ImportRequestResponse(url, request, response);
    92  - requests.add(x);
     102 + requests.add(requestResponse);
    93 103   
    94 104   } catch (Exception e) {
    95  - LoggerPlusPlus.callbacks.printError("LoggerImport-importWStalker: Error Parsing Content");
    96  - return new ArrayList<IHttpRequestResponse>();
     105 + log.error("LoggerImport-importWStalker: Error Parsing Content");
     106 + return new ArrayList<>();
    97 107   }
    98 108   }
    99 109   
    100 110   return requests;
    101 111   }
    102 112   
    103  - public static ArrayList<IHttpRequestResponse> importZAP() {
     113 + public static ArrayList<HttpRequestResponse> importZAP() {
    104 114   ArrayList<String> lines = new ArrayList<String>();
    105  - ArrayList<IHttpRequestResponse> requests = new ArrayList<IHttpRequestResponse>();
    106  - IExtensionHelpers helpers = LoggerPlusPlus.callbacks.getHelpers();
     115 + ArrayList<HttpRequestResponse> requests = new ArrayList<HttpRequestResponse>();
    107 116  
    108 117   String filename = getLoadFile();
    109 118   if ( filename.length() == 0 ) { // exit if no file selected
    110  - return new ArrayList<IHttpRequestResponse>();
     119 + return new ArrayList<HttpRequestResponse>();
    111 120   }
    112 121   
    113 122   lines = readFile(filename);
    skipped 25 lines
    139 148   if ( line.matches(reSeparator) || !i.hasNext() ) {
    140 149   // TODO: Remove one or two \n at the end of requestBuffer
    141 150   
    142  - byte[] req = helpers.stringToBytes(requestBuffer);
    143  - byte[] res = helpers.stringToBytes(responseBuffer);
     151 + HttpService httpService = HttpService.httpService(url);
     152 + HttpRequest httpRequest = HttpRequest.httpRequest(httpService, requestBuffer);
     153 + HttpResponse httpResponse = HttpResponse.httpResponse(responseBuffer);
     154 + HttpRequestResponse requestResponse = HttpRequestResponse.httpRequestResponse(httpRequest, httpResponse);
    144 155   
    145  - // Add IHttpRequestResponse Object
    146  - ImportRequestResponse x = new ImportRequestResponse(url, req, res);
    147  - requests.add(x);
     156 + requests.add(requestResponse);
    148 157   
    149 158   // Reset content
    150 159   isRequest = true;
    skipped 16 lines
    167 176   line = x[0] + " " + path + " " + x[2]; // fix the path in the request
    168 177   
    169 178   } catch (Exception e) {
    170  - LoggerPlusPlus.callbacks.printError("importZAP: Wrong Path Format");
     179 + log.error("importZAP: Wrong Path Format");
    171 180   return new ArrayList<>();
    172 181   }
    173 182   }
    skipped 16 lines
    190 199   return requests;
    191 200   }
    192 201   
    193  - public static boolean loadImported(ArrayList<IHttpRequestResponse> requests, Boolean sendToAutoExporters) {
     202 + public static boolean loadImported(ArrayList<HttpRequestResponse> requests, Boolean sendToAutoExporters) {
    194 203   EntryImportWorker importWorker = LoggerPlusPlus.instance.getLogProcessor().createEntryImportBuilder()
    195  - .setOriginatingTool(IBurpExtenderCallbacks.TOOL_EXTENDER)
    196  - .setEntries(requests)
     204 + .setOriginatingTool(ToolType.EXTENSIONS)
     205 + .setHttpEntries(requests)
    197 206   .setInterimConsumer(integers -> {
    198 207   //Optional
    199 208   //Outputs chunks of integers representing imported indices
    skipped 11 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/logentry/LogEntry.java
    skipped 12 lines
    13 13   
    14 14  package com.nccgroup.loggerplusplus.logentry;
    15 15   
    16  -import burp.*;
     16 +import burp.api.montoya.core.ToolType;
     17 +import burp.api.montoya.http.HttpService;
     18 +import burp.api.montoya.http.message.Cookie;
     19 +import burp.api.montoya.http.message.HttpHeader;
     20 +import burp.api.montoya.http.message.MimeType;
     21 +import burp.api.montoya.http.message.params.HttpParameter;
     22 +import burp.api.montoya.http.message.params.HttpParameterType;
     23 +import burp.api.montoya.http.message.requests.HttpRequest;
     24 +import burp.api.montoya.http.message.responses.HttpResponse;
    17 25  import com.nccgroup.loggerplusplus.LoggerPlusPlus;
    18  -import com.nccgroup.loggerplusplus.filter.colorfilter.ColorFilter;
     26 +import com.nccgroup.loggerplusplus.filter.colorfilter.TableColorRule;
    19 27  import com.nccgroup.loggerplusplus.filter.tag.Tag;
    20 28  import com.nccgroup.loggerplusplus.logview.processor.LogProcessor;
    21  -import com.nccgroup.loggerplusplus.logview.processor.LogProcessorHelper;
    22 29  import com.nccgroup.loggerplusplus.reflection.ReflectionController;
    23 30  import com.nccgroup.loggerplusplus.util.Globals;
    24 31  import lombok.AccessLevel;
    skipped 2 lines
    27 34  import org.apache.commons.codec.digest.DigestUtils;
    28 35  import org.apache.commons.lang3.StringUtils;
    29 36   
     37 +import java.net.MalformedURLException;
    30 38  import java.net.URL;
    31  -import java.nio.charset.StandardCharsets;
    32 39  import java.text.ParseException;
    33 40  import java.util.*;
    34 41  import java.util.regex.Matcher;
    skipped 6 lines
    41 48   Status previousStatus;
    42 49   Status status = Status.UNPROCESSED;
    43 50   
    44  - @Getter(AccessLevel.NONE)
     51 + @Setter(AccessLevel.NONE)
     52 + private HttpRequest request;
    45 53   @Setter(AccessLevel.NONE)
    46  - private IHttpRequestResponse requestResponse; //Only used for request, comment and HTTP Service.
    47  - private byte[] response;
     54 + private HttpResponse response;
    48 55   
    49 56   private Integer identifier;
    50  - private int tool;
    51  - private String toolName;
     57 + private ToolType tool;
    52 58   private String hostname = "";
    53 59   private String host = ""; // TODO better name?
    54 60   private String method = "";
     61 + private String urlString;
    55 62   private URL url;
    56 63   private boolean params = false;
    57 64   private Short responseStatus = -1;
    skipped 2 lines
    60 67   private boolean hasBodyParam = false;
    61 68   private boolean hasCookieParam = false;
    62 69   private String title = "";
    63  - private String newCookies = "";
     70 + private String comment;
     71 + private List<String> newCookies = new ArrayList<>();
    64 72   private String sentCookies = "";
    65 73   private String listenerInterface = "";
    66 74   private boolean isSSL = false;
    skipped 7 lines
    74 82   private String clientIP = "";
    75 83   private boolean hasSetCookies = false;
    76 84   private String formattedResponseTime = "";
    77  - private String responseMimeType = "";
    78  - private String responseInferredMimeType = "";
     85 + private MimeType responseMimeType;
     86 + private MimeType responseInferredMimeType;
    79 87   private int responseBodyLength = -1;
    80 88   private String responseContentType = "";
    81 89   private boolean complete = false;
    skipped 10 lines
    92 100   private Date responseDateTime = new Date(0); //Zero epoch dates to prevent null. Response date pulled from response headers
    93 101   private Date requestDateTime = new Date(0); //Zero epoch dates to prevent null. Response date pulled from response headers
    94 102   private int requestResponseDelay = -1;
    95  - private List<String> responseHeaders;
    96  - private List<String> requestHeaders;
    97  - private List<IParameter> tempParameters;
     103 + private List<HttpHeader> responseHeaders;
     104 + private List<HttpHeader> requestHeaders;
    98 105   private List<String> parameters;
    99 106   private List<String> reflectedParameters;
    100 107   
    101 108   private LogEntry() {
    102  - this.matchingColorFilters = Collections.synchronizedList(new ArrayList<UUID>());
    103  - this.matchingTags = Collections.synchronizedList(new ArrayList<Tag>());
     109 + this.matchingColorFilters = Collections.synchronizedList(new ArrayList<>());
     110 + this.matchingTags = Collections.synchronizedList(new ArrayList<>());
    104 111   }
    105 112   
    106  - public LogEntry(int tool, IHttpRequestResponse requestResponse) {
     113 + public LogEntry(ToolType tool, HttpRequest request) {
    107 114   this();
    108 115   this.tool = tool;
    109  - this.toolName = LoggerPlusPlus.callbacks.getToolName(tool);
    110  - this.requestResponse = requestResponse;
    111  - this.response = requestResponse.getResponse();
     116 + this.request = request;
     117 + }
     118 + 
     119 + public LogEntry(ToolType tool, HttpRequest request, HttpResponse response){
     120 + this(tool, request);
     121 + this.response = response;
    112 122   }
    113 123   
    114 124   /**
    115 125   * Create new entry and specify arrival time.
    116 126   *
    117 127   * @param tool
     128 + * @param request
    118 129   * @param formattedRequestTime
    119  - * @param requestResponse
    120 130   */
    121  - public LogEntry(int tool, Date formattedRequestTime, IHttpRequestResponse requestResponse) {
    122  - this(tool, requestResponse);
     131 + public LogEntry(ToolType tool, HttpRequest request, Date formattedRequestTime) {
     132 + this(tool, request);
    123 133   this.setReqestTime(formattedRequestTime);
    124 134   }
    125 135   
    126  - public void process() {
    127  - // TODO Move into separate processing class
     136 + public boolean process() {
    128 137   previousStatus = this.status;
    129 138   switch (this.status) {
    130 139   case UNPROCESSED: {
    131 140   this.status = processRequest();
    132  - // If the entry should be ignored, break here.
     141 + // If the entry should be ignored, stop here.
    133 142   if (this.status == Status.IGNORED)
    134  - break;
     143 + return true;
    135 144   
    136 145   // Else continue, fall through to process response
    137 146   }
    138 147   case AWAITING_RESPONSE: {
    139 148   if (this.response == null) {
    140 149   this.status = Status.AWAITING_RESPONSE;
    141  - break;
     150 + return false;
    142 151   }
    143 152   processResponse();
    144 153   this.status = Status.PROCESSED;
     154 + return true;
    145 155   }
    146 156   
    147 157   case IGNORED:
    148 158   case PROCESSED: {
    149 159   // Nothing to do, we're done!
    150  - break;
     160 + return true;
    151 161   }
     162 + 
     163 + default: return false;
    152 164   }
    153 165   }
    154 166   
    skipped 11 lines
    166 178   }
    167 179   
    168 180   private Status processRequest() {
    169  - IRequestInfo tempAnalyzedReq = LoggerPlusPlus.callbacks.getHelpers().analyzeRequest(this.requestResponse);
    170  - URL uUrl = tempAnalyzedReq.getUrl();
    171  - if (!LoggerPlusPlus.isUrlInScope(uUrl))
    172  - return Status.IGNORED;
     181 + 
    173 182   
    174  - requestHeaders = tempAnalyzedReq.getHeaders();
     183 + requestHeaders = request.headers();
    175 184   
    176 185   // Get HTTP Version, which would be the last token in "GET /admin/login/?next\u003d/admin/ HTTP/1.1"
    177  - String[] httpRequestTokens = requestHeaders.get(0).split(" ");
     186 + String[] httpRequestTokens = requestHeaders.get(0).value().split(" ");
    178 187   this.requestHttpVersion = httpRequestTokens[httpRequestTokens.length - 1];
    179 188   
    180  - this.tempParameters = tempAnalyzedReq.getParameters().stream()
    181  - .filter(iParameter -> iParameter.getType() != IParameter.PARAM_COOKIE).collect(Collectors.toList());
    182  - this.parameters = tempParameters.stream().map(IParameter::getName).collect(Collectors.toList());
     189 + this.parameters = request.parameters().stream()
     190 + .filter(param -> param.type() != HttpParameterType.COOKIE)
     191 + .map(HttpParameter::name)
     192 + .collect(Collectors.toList());
    183 193   
    184  - this.url = tempAnalyzedReq.getUrl();
    185  - this.hostname = this.requestResponse.getHttpService().getHost();
    186  - this.protocol = this.requestResponse.getHttpService().getProtocol();
    187  - this.isSSL = this.protocol.equals("https");
    188  - this.targetPort = this.requestResponse.getHttpService().getPort();
     194 + this.urlString = request.url();
     195 + this.hostname = this.request.httpService().host();
     196 + this.protocol = this.request.httpService().secure() ? "https" : "http";
     197 + this.isSSL = this.request.httpService().secure();
     198 + this.targetPort = this.request.httpService().port();
    189 199   
    190 200   boolean isDefaultPort = (this.protocol.equals("https") && this.targetPort == 443)
    191 201   || (this.protocol.equals("http") && this.targetPort == 80);
    192 202   
    193 203   this.host = this.protocol + "://" + this.hostname + (isDefaultPort ? "" : ":" + this.targetPort);
    194 204   
    195  - this.method = tempAnalyzedReq.getMethod();
     205 + this.method = request.method();
     206 + this.requestBodyLength = this.getRequestBytes().length - request.bodyOffset();
     207 + this.hasBodyParam = requestBodyLength > 0;
     208 + 
    196 209   try {
     210 + this.url = new URL(request.url());
     211 + 
    197 212   // I don't want to delete special characters such as ; or : from the extension
    198 213   // as it may really be part of the extension! (burp proxy log ignores them)
    199  - String tempPath = this.url.getPath().replaceAll("\\\\", "/");
     214 + String tempPath = url.getPath().replaceAll("\\\\", "/");
    200 215   tempPath = tempPath.substring(tempPath.lastIndexOf("/"));
    201 216   int tempPathDotLocation = tempPath.lastIndexOf(".");
    202  - if (tempPathDotLocation >= 0)
     217 + if (tempPathDotLocation >= 0) {
    203 218   this.urlExtension = tempPath.substring(tempPathDotLocation + 1);
    204  - } catch (Exception e) {
    205  - this.urlExtension = "";
    206  - }
     219 + }
     220 + this.params = url.getQuery() != null || this.hasBodyParam;
     221 + } catch (MalformedURLException ignored) {}
    207 222   
    208  - this.requestBodyLength = this.getRequest().length - tempAnalyzedReq.getBodyOffset();
    209  - this.hasBodyParam = requestBodyLength > 0;
    210  - this.params = this.url.getQuery() != null || this.hasBodyParam;
    211  - this.hasCookieParam = false;
     223 + 
     224 + 
    212 225   
    213 226   // reading request headers like a boss!
    214  - for (String item : requestHeaders) {
    215  - if (item.contains(":")) {
    216  - String[] headerItem = item.split(":\\s", 2);
    217  - if (headerItem[0].equalsIgnoreCase("cookie")) {
    218  - this.sentCookies = headerItem[1];
     227 + for (HttpHeader header : requestHeaders) {
     228 +// if (header.contains(":")) {
     229 + if (header.name().equalsIgnoreCase("cookie")) {
     230 + this.sentCookies = header.value();
    219 231   if (!this.sentCookies.isEmpty()) {
    220 232   this.hasCookieParam = true;
    221 233   this.sentCookies += ";"; // we need to ad this to search it in cookie Jar!
    222 234   
    223 235   // Check to see if it uses cookie Jars!
    224  - List<ICookie> cookieJars = LoggerPlusPlus.callbacks.getCookieJarContents();
     236 + List<Cookie> cookiesInJar = LoggerPlusPlus.montoya.http().cookieJar().cookies();
    225 237   boolean oneNotMatched = false;
    226 238   boolean anyParamMatched = false;
    227 239   
    228  - for (ICookie cookieItem : cookieJars) {
    229  - if (cookieItem.getDomain().equals(this.hostname)) {
     240 + for (Cookie cookieItem : cookiesInJar) {
     241 + if (cookieItem.domain().equals(this.hostname)) {
    230 242   // now we want to see if any of these cookies have been set here!
    231  - String currentCookieJarParam = cookieItem.getName() + "=" + cookieItem.getValue() + ";";
     243 + String currentCookieJarParam = cookieItem.name() + "=" + cookieItem.value() + ";";
    232 244   if (this.sentCookies.contains(currentCookieJarParam)) {
    233 245   anyParamMatched = true;
    234 246   } else {
    skipped 10 lines
    245 257   this.usesCookieJar = CookieJarStatus.YES;
    246 258   }
    247 259   }
    248  - } else if (headerItem[0].equalsIgnoreCase("referer")) {
    249  - this.referrerURL = headerItem[1];
    250  - } else if (headerItem[0].equalsIgnoreCase("content-type")) {
    251  - this.requestContentType = headerItem[1];
    252  - } else if (headerItem[0].equalsIgnoreCase("origin")) {
    253  - this.origin = headerItem[1];
     260 + } else if (header.name().equalsIgnoreCase("referer")) {
     261 + this.referrerURL = header.value();
     262 + } else if (header.name().equalsIgnoreCase("content-type")) {
     263 + this.requestContentType = header.value();
     264 + } else if (header.name().equalsIgnoreCase("origin")) {
     265 + this.origin = header.value();
    254 266   }
    255  - }
     267 +// }
    256 268   }
    257 269   
    258 270   return Status.AWAITING_RESPONSE;
    skipped 44 lines
    303 315   //// this.regexAllReq[i] = allMatches.toString();
    304 316   //
    305 317   // }catch(Exception e){
    306  - // LoggerPlusPlus.callbacks.printError("Error in regular expression: " +
     318 + // LoggerPlusPlus.montoya.printError("Error in regular expression: " +
    307 319   // regexString);
    308 320   // }
    309 321   //
    skipped 7 lines
    317 329   * @param requestResponse
    318 330   * @param arrivalTime
    319 331   */
    320  - public void addResponse(IHttpRequestResponse requestResponse, Date arrivalTime) {
     332 + public void addResponse(HttpResponse requestResponse, Date arrivalTime) {
    321 333   this.responseDateTime = arrivalTime;
    322 334   
    323 335   //IHttpRequestResponse objects received by the proxy listener do not contain the latest request.
    324 336   //So we must store the content separately.
    325  - this.response = requestResponse.getResponse();
    326  - this.setComment(requestResponse.getComment()); //Update the comment with the current comment
     337 + this.response = requestResponse;
     338 +// this.setComment(requestResponse.getComment()); //Update the comment with the current comment
    327 339   }
    328 340   
    329 341   private Status processResponse() {
    330 342   reflectedParameters = new ArrayList<>();
    331  - IResponseInfo tempAnalyzedResp = LoggerPlusPlus.callbacks.getHelpers()
    332  - .analyzeResponse(response);
     343 +// IResponseInfo tempAnalyzedResp = LoggerPlusPlus.montoya.getHelpers()
     344 +// .analyzeResponse(response);
    333 345   
    334  - this.responseStatus = tempAnalyzedResp.getStatusCode();
    335  - this.responseBodyLength = response.length - tempAnalyzedResp.getBodyOffset();
    336  - this.responseMimeType = tempAnalyzedResp.getStatedMimeType();
    337  - this.responseInferredMimeType = tempAnalyzedResp.getInferredMimeType();
     346 + this.responseStatus = response.statusCode();
     347 + this.responseBodyLength = response.body().length();
     348 + this.responseMimeType = response.statedMimeType();
     349 + this.responseInferredMimeType = response.inferredMimeType();
    338 350   
    339 351   /**************************************
    340 352   ************HEADER PROCESSING*********
    341 353   **************************************/
    342 354   
    343  - //Fancy handling to combine duplicate headers into CSVs.
    344  - Map<String, String> headers = tempAnalyzedResp.getHeaders().stream().filter(s -> s.contains(":"))
    345  - .collect(Collectors.toMap(s -> {
    346  - String[] split = s.split(": ", 2);
    347  - return split.length > 0 ? split[0] : "";
    348  - }, s -> {
    349  - String[] split = s.split(": ", 2);
    350  - if (split.length > 1) {
    351  - return split[1];
    352  - }
    353  - return "";
    354  - }, (s, s2) -> {
     355 + Map<String, String> headers = response.headers().stream()
     356 + .collect(Collectors.toMap(HttpHeader::name, HttpHeader::value, (s, s2) -> {
    355 357   s += ", " + s2;
    356 358   return s;
    357 359   }, () -> new TreeMap<>(String.CASE_INSENSITIVE_ORDER)));
    358 360   
    359  - responseHeaders = tempAnalyzedResp.getHeaders();
     361 + responseHeaders = response.headers();
    360 362   
    361 363   if (headers.containsKey("Location")) {
    362 364   this.redirectURL = headers.get("Location");
    363 365   }
    364 366   
    365 367   // Extract HTTP Status message
    366  - String[] httpStatusTokens = responseHeaders.get(0).split(" ");
    367  - this.responseStatusText = httpStatusTokens[httpStatusTokens.length - 1];
    368  - this.responseHttpVersion = httpStatusTokens[0];
     368 + HttpHeader httpStatusTokens = response.headers().get(0);
     369 + //TODO FixMe
     370 +// this.responseStatusText = httpStatusTokens[httpStatusTokens.length - 1];
     371 +// this.responseHttpVersion = httpStatusTokens[0];
     372 + 
    369 373   
    370 374   if (headers.containsKey("content-type")) {
    371 375   this.responseContentType = headers.get("content-type");
    372 376   }
    373 377   
    374 378   //Cookies
    375  - for (ICookie cookieItem : tempAnalyzedResp.getCookies()) {
    376  - this.newCookies += cookieItem.getName() + "=" + cookieItem.getValue() + "; "; //TODO convert to map, and add filter support for maps
    377  - }
     379 + this.newCookies = response.cookies().stream().map(cookie -> String.format("%s=%s", cookie.name(), cookie.value())).collect(Collectors.toList());
    378 380   this.hasSetCookies = !newCookies.isEmpty();
    379 381   
    380 382   
    skipped 27 lines
    408 410   **************************************/
    409 411   
    410 412   Long maxRespSize = ((Integer) LoggerPlusPlus.instance.getPreferencesController().getPreferences().getSetting(Globals.PREF_MAX_RESP_SIZE)) * 1000000L;
    411  - int bodyOffset = response.length - responseBodyLength;
     413 + int bodyOffset = response.bodyOffset();
    412 414   if (responseBodyLength < maxRespSize) {
    413 415   //Only title match HTML files. Prevents expensive regex running on e.g. binary downloads.
    414  - if (this.responseInferredMimeType.equalsIgnoreCase("HTML")) {
    415  - String strFullResponse = new String(response);
    416  - Matcher titleMatcher = Globals.HTML_TITLE_PATTERN.matcher(strFullResponse);
     416 + if (this.responseInferredMimeType == MimeType.HTML) {
     417 + Matcher titleMatcher = Globals.HTML_TITLE_PATTERN.matcher(response.bodyToString());
    417 418   if (titleMatcher.find()) {
    418 419   this.title = titleMatcher.group(1);
    419 420   }
    420 421   }
    421 422   
    422  - String responseBody = new String(response, bodyOffset, responseBodyLength);
    423 423   ReflectionController reflectionController = LoggerPlusPlus.instance.getReflectionController();
    424  - reflectedParameters = tempParameters.parallelStream()
    425  - .filter(iParameter -> !reflectionController.isParameterFiltered(iParameter)
    426  - && reflectionController.validReflection(responseBody, iParameter))
    427  - .map(IParameter::getName).collect(Collectors.toList());
     424 + reflectedParameters = request.parameters().parallelStream()
     425 + .filter(parameter -> !reflectionController.isParameterFiltered(parameter) && reflectionController.validReflection(response.bodyToString(), parameter))
     426 + .map(HttpParameter::name).collect(Collectors.toList());
    428 427   
    429  -// this.requestResponse = LoggerPlusPlus.callbacks.saveBuffersToTempFiles(requestResponse);
     428 +// this.requestResponse = LoggerPlusPlus.montoya.saveBuffersToTempFiles(requestResponse);
    430 429   } else {
    431 430   //Just look for reflections in the headers.
    432 431   ReflectionController reflectionController = LoggerPlusPlus.instance.getReflectionController();
    433  - reflectedParameters = tempParameters.parallelStream()
    434  - .filter(iParameter -> !reflectionController.isParameterFiltered(iParameter)
    435  - && reflectionController.validReflection(new String(response, 0, bodyOffset), iParameter))
    436  - .map(IParameter::getName).collect(Collectors.toList());
     432 + reflectedParameters = request.parameters().parallelStream()
     433 + .filter(parameter -> !reflectionController.isParameterFiltered(parameter)
     434 + && reflectionController.validReflection(response.bodyToString(), parameter))
     435 + .map(HttpParameter::name).collect(Collectors.toList());
    437 436   
    438 437   //Trim the response down to a maximum size, but at least keep the headers!
    439  - this.response = (new String(this.response, 0, bodyOffset) + "Response body trimmed by Logger++. To prevent this, increase \"Maximum Response Size\" in the Logger++ options.").getBytes(StandardCharsets.UTF_8);
     438 + //TODO Fix response trimming?
     439 +// this.response = (new String(this.response, 0, bodyOffset) + "Response body trimmed by Logger++. To prevent this, increase \"Maximum Response Size\" in the Logger++ options.").getBytes(StandardCharsets.UTF_8);
    440 440   }
    441  - 
    442  - 
    443  - tempParameters = null; // We're done with these. Allow them to be cleaned.
    444 441   
    445 442   this.complete = true;
    446 443   
    skipped 40 lines
    487 484   // this.regexAllResp[i] = allMatches.toString();
    488 485   //
    489 486   // }catch(Exception e){
    490  - // LoggerPlusPlus.callbacks.printError("Error in regular expression: " +
     487 + // LoggerPlusPlus.montoya.printError("Error in regular expression: " +
    491 488   // regexString);
    492 489   // }
    493 490   //
    skipped 7 lines
    501 498   // }
    502 499   }
    503 500   
    504  - public byte[] getRequest() {
    505  - return this.requestResponse.getRequest();
     501 + public byte[] getRequestBytes() {
     502 + return this.request.toByteArray().getBytes();
    506 503   }
    507 504   
    508  - public byte[] getResponse() {
    509  - return response;
     505 + public byte[] getResponseBytes() {
     506 + return response.toByteArray().getBytes();
    510 507   }
    511 508   
    512 509   public void setReqestTime(Date requestTime) {
    skipped 7 lines
    520 517   }
    521 518   
    522 519   public void setComment(String comment) {
    523  - this.requestResponse.setComment(comment);
     520 + this.comment = comment;
    524 521   }
    525 522   
    526 523   public String getComment() {
    527  - return this.requestResponse.getComment();
     524 + return this.comment;
    528 525   }
    529 526   
    530 527   
    skipped 3 lines
    534 531   switch (columnName) {
    535 532   case PROXY_TOOL:
    536 533   case REQUEST_TOOL:
    537  - return getToolName();
     534 + return tool.toolName();
    538 535   case TAGS:
    539  - return this.matchingTags.stream().map(Tag::getName).collect(Collectors.toList());
     536 + return this.matchingTags.stream().collect(Collectors.toList());
    540 537   case URL:
    541  - return this.url;
     538 + return this.urlString;
    542 539   case PATH:
    543  - return this.url.getPath();
     540 + return (this.url != null ? this.url.getPath() : "");
    544 541   case QUERY:
    545  - return this.url.getQuery();
     542 + return (this.url != null ? this.url.getQuery() : "");
    546 543   case PATHQUERY:
    547 544   return this.url.getFile();
    548 545   case STATUS:
    skipped 21 lines
    570 567   case RESPONSE_TIME:
    571 568   return this.responseDateTime;
    572 569   case COMMENT:
    573  - return this.requestResponse.getComment();
     570 + return this.comment;
    574 571   case REQUEST_CONTENT_TYPE:
    575 572   return this.requestContentType;
    576 573   case REQUEST_HTTP_VERSION:
    skipped 7 lines
    584 581   case PARAMETER_COUNT:
    585 582   return this.parameters.size();
    586 583   case HASGETPARAM:
    587  - return this.url.getQuery() != null;
     584 + return this.url != null && this.url.getQuery() != null;
    588 585   case HASPOSTPARAM:
    589 586   return this.hasBodyParam;
    590 587   case HASCOOKIEPARAM:
    skipped 51 lines
    642 639   case REFLECTION_COUNT:
    643 640   return reflectedParameters.size();
    644 641   case REQUEST_BODY: // request
    645  - if (requestBodyLength == 0) return "";
    646  - return new String(getRequest(), getRequest().length - requestBodyLength, requestBodyLength);
     642 + return request.bodyToString();
     643 + case REQUEST_BODY_LENGTH:
     644 + return request.body().length();
    647 645  // .substring(request.length - requestBodyLength);
    648 646   case RESPONSE_BODY: // response
    649  - if (responseBodyLength == 0) return "";
    650  - return new String(response, response.length - responseBodyLength, responseBodyLength);
    651  -// .substring(response.length - responseBodyLength);
     647 + return response.bodyToString();
     648 + case RESPONSE_BODY_LENGTH:
     649 + return response.body().length();
    652 650   case RTT:
    653 651   return requestResponseDelay;
    654 652   case REQUEST_HEADERS:
    655  - return requestHeaders != null ? String.join("\r\n", requestHeaders) : "";
     653 + return requestHeaders != null ? requestHeaders.stream().map(HttpHeader::toString).collect(Collectors.joining("\r\n")) : "";
    656 654   case RESPONSE_HEADERS:
    657  - return responseHeaders != null ? String.join("\r\n", responseHeaders) : "";
     655 + return responseHeaders != null ? responseHeaders.stream().map(HttpHeader::toString).collect(Collectors.joining("\r\n")) : "";
    658 656   case REDIRECT_URL:
    659 657   return redirectURL;
    660 658   case BASE64_REQUEST:
    661  - return Base64.getEncoder().encodeToString(this.getRequest());
     659 + return Base64.getEncoder().encodeToString(this.getRequestBytes());
    662 660   case BASE64_RESPONSE:
    663  - return Base64.getEncoder().encodeToString(response);
     661 + return Base64.getEncoder().encodeToString(this.getResponseBytes());
    664 662   case RESPONSE_HASH: {
    665 663   if (responseHash == null) {
    666 664   responseHash = DigestUtils
    skipped 17 lines
    684 682   return matchingTags;
    685 683   }
    686 684   
    687  - public IHttpService getHttpService() {
    688  - return this.requestResponse.getHttpService();
     685 + public HttpService getHttpService() {
     686 + return this.request.httpService();
    689 687   }
    690 688   
    691 689   public enum CookieJarStatus {
    skipped 14 lines
    706 704   /**
    707 705   * TODO CLEAN UP
    708 706   *
    709  - * @param colorFilter
     707 + * @param tableColorRule
    710 708   * @param retest
    711 709   * @return If the list of matching color filters was updated
    712 710   */
    713  - public boolean testColorFilter(ColorFilter colorFilter, boolean retest) {
    714  - if (!colorFilter.isEnabled() || colorFilter.getFilter() == null) {
    715  - return this.getMatchingColorFilters().remove(colorFilter.getUUID());
     711 + public boolean testColorFilter(TableColorRule tableColorRule, boolean retest) {
     712 + if (!tableColorRule.isEnabled() || tableColorRule.getFilterExpression() == null) {
     713 + return this.getMatchingColorFilters().remove(tableColorRule.getUuid());
    716 714   }
    717 715   
    718 716   // If we don't already know if the color filter matches (e.g. haven't checked it
    719 717   // before)
    720  - if (!this.matchingColorFilters.contains(colorFilter.getUUID())) {
    721  - if (colorFilter.getFilter().matches(this)) {
    722  - this.matchingColorFilters.add(colorFilter.getUUID());
     718 + if (!this.matchingColorFilters.contains(tableColorRule.getUuid())) {
     719 + if (tableColorRule.getFilterExpression().matches(this)) {
     720 + this.matchingColorFilters.add(tableColorRule.getUuid());
    723 721   return true;
    724 722   } else {
    725 723   return false;
    726 724   }
    727 725   } else if (retest) { // Or if we are forcing a retest (e.g. filter was updated)
    728  - if (!colorFilter.getFilter().matches(this)) {
    729  - this.matchingColorFilters.remove(colorFilter.getUUID());
     726 + if (!tableColorRule.getFilterExpression().matches(this)) {
     727 + this.matchingColorFilters.remove(tableColorRule.getUuid());
    730 728   }
    731 729   return true;
    732 730   } else {
    skipped 7 lines
    740 738   * @return If the list of matching color filters was updated
    741 739   */
    742 740   public boolean testTag(Tag tag, boolean retest) {
    743  - if (!tag.isEnabled() || tag.getFilter() == null) {
     741 + if (!tag.isEnabled() || tag.getFilterExpression() == null) {
    744 742   return this.getMatchingTags().remove(tag);
    745 743   }
    746 744   
    747 745   // If we don't already know if the color filter matches (e.g. haven't checked it
    748 746   // before)
    749 747   if (!this.matchingTags.contains(tag)) {
    750  - if (tag.getFilter().matches(this)) {
     748 + if (tag.getFilterExpression().matches(this)) {
    751 749   this.matchingTags.add(tag);
    752 750   return true;
    753 751   } else {
    754 752   return false;
    755 753   }
    756 754   } else if (retest) { // Or if we are forcing a retest (e.g. filter was updated)
    757  - if (!tag.getFilter().matches(this)) {
     755 + if (!tag.getFilterExpression().matches(this)) {
    758 756   this.matchingTags.remove(tag);
    759 757   }
    760 758   return true;
    skipped 4 lines
    765 763   
    766 764   @Override
    767 765   public String toString() {
    768  - return this.url.toString();
     766 + return this.urlString.toString();
    769 767   }
    770 768   
    771  - public static Integer extractAndRemoveIdentifierFromComment(LogEntry logEntry) {
    772  - return LogProcessorHelper.extractAndRemoveIdentifierFromRequestResponseComment(logEntry.requestResponse);
    773  - }
     769 +// public static Integer extractAndRemoveIdentifierFromComment(LogEntry logEntry) {
     770 +// return LogProcessorHelper.extractAndRemoveIdentifierFromRequestResponseComment(logEntry.request);
     771 +// }
    774 772  }
    775 773   
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/logentry/LogEntryField.java
    skipped 18 lines
    19 19   BASE64_REQUEST(FieldGroup.REQUEST, String.class, "The entire request encoded in Base64", "AsBase64"),
    20 20   REQUEST_HEADERS(FieldGroup.REQUEST, String.class, "The request line and associated headers.", "Headers", "Header"),
    21 21   REQUEST_BODY(FieldGroup.REQUEST, String.class, "The request body.", "Body"),
     22 + REQUEST_BODY_LENGTH(FieldGroup.REQUEST, String.class, "The request body's length.", "BodyLength"),
    22 23   REQUEST_TIME(FieldGroup.REQUEST, Date.class, "Date and time of inital request (as received by L++).", "Time"),
    23 24   REQUEST_LENGTH(FieldGroup.REQUEST, Integer.class, "The length of the received request.", "Length"),
    24 25   REQUEST_TOOL(FieldGroup.REQUEST, String.class, "The tool used to initiate the request.", "Tool"), //Alias for proxy.tool,
    skipped 27 lines
    52 53   BASE64_RESPONSE(FieldGroup.RESPONSE, String.class, "The entire response encoded in Base64", "AsBase64"),
    53 54   RESPONSE_HEADERS(FieldGroup.RESPONSE, String.class, "The status line and associated headers.", "Headers", "Header"),
    54 55   RESPONSE_BODY(FieldGroup.RESPONSE, String.class, "The response body.", "Body"),
     56 + RESPONSE_BODY_LENGTH(FieldGroup.RESPONSE, String.class, "The response body's length.", "BodyLength"),
    55 57   RESPONSE_HASH(FieldGroup.RESPONSE, String.class, "SHA1 Hash of the response", "hash", "sha1"),
    56 58   RESPONSE_TIME(FieldGroup.RESPONSE, Date.class, "Date and time of receiving the response (as received by L++).", "Time"),
    57 59   RESPONSE_LENGTH(FieldGroup.RESPONSE, Integer.class, "The length of the received response.", "Length"),
    skipped 95 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/logentry/LogEntryFieldSerializer.java
    skipped 2 lines
    3 3  import com.google.gson.*;
    4 4   
    5 5  import java.lang.reflect.Type;
    6  -import java.util.Collection;
    7  -import java.util.Date;
    8  -import java.util.HashMap;
    9  -import java.util.LinkedHashMap;
    10 6   
    11 7  public class LogEntryFieldSerializer implements JsonSerializer<LogEntryField>, JsonDeserializer<LogEntryField> {
    12 8   
    skipped 11 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/logging/BurpAppender.java
     1 +package com.nccgroup.loggerplusplus.logging;
     2 + 
     3 +import com.nccgroup.loggerplusplus.LoggerPlusPlus;
     4 +import org.apache.logging.log4j.Level;
     5 +import org.apache.logging.log4j.core.Appender;
     6 +import org.apache.logging.log4j.core.Core;
     7 +import org.apache.logging.log4j.core.Filter;
     8 +import org.apache.logging.log4j.core.LogEvent;
     9 +import org.apache.logging.log4j.core.appender.AbstractAppender;
     10 +import org.apache.logging.log4j.core.config.plugins.Plugin;
     11 +import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
     12 +import org.apache.logging.log4j.core.config.plugins.PluginElement;
     13 +import org.apache.logging.log4j.core.config.plugins.PluginFactory;
     14 +import org.apache.logging.log4j.core.layout.PatternLayout;
     15 + 
     16 +@Plugin(name="BurpAppender", category = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE)
     17 +public class BurpAppender extends AbstractAppender {
     18 + 
     19 + public BurpAppender(String name, Filter filter){
     20 + super(name, filter, PatternLayout.createDefaultLayout(), false, null);
     21 + System.out.println("Created appender");
     22 + }
     23 + 
     24 + @PluginFactory
     25 + public static BurpAppender createAppender(@PluginAttribute("name") String name, @PluginElement("Filter") Filter filter) {
     26 + return new BurpAppender(name, filter);
     27 + }
     28 + 
     29 + @Override
     30 + public void append(LogEvent event) {
     31 + String message = new String(this.getLayout().toByteArray(event));
     32 + if(LoggerPlusPlus.montoya == null) return;
     33 + 
     34 + if (event.getLevel().isInRange(Level.WARN, Level.FATAL)) {
     35 + LoggerPlusPlus.montoya.logging().logToError(message);
     36 + } else {
     37 + LoggerPlusPlus.montoya.logging().logToOutput(message);
     38 + }
     39 + }
     40 +}
     41 + 
  • ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/logging/LoggingController.java
    1 1  package com.nccgroup.loggerplusplus.logging;
    2 2   
    3  -import burp.IBurpExtenderCallbacks;
     3 +import burp.api.montoya.MontoyaApi;
    4 4  import com.coreyd97.BurpExtenderUtilities.IGsonProvider;
    5  -import com.nccgroup.loggerplusplus.LoggerPlusPlus;
    6 5  import com.nccgroup.loggerplusplus.util.Globals;
     6 +import lombok.extern.log4j.Log4j2;
    7 7  import org.apache.logging.log4j.Level;
    8 8  import org.apache.logging.log4j.LogManager;
    9  -import org.apache.logging.log4j.core.Appender;
    10  -import org.apache.logging.log4j.core.LogEvent;
    11 9  import org.apache.logging.log4j.core.LoggerContext;
    12  -import org.apache.logging.log4j.core.appender.AbstractAppender;
    13  -import org.apache.logging.log4j.core.config.Configuration;
    14  -import org.apache.logging.log4j.core.layout.PatternLayout;
    15 10   
     11 +@Log4j2
    16 12  public class LoggingController {
    17 13   
    18 14   private final IGsonProvider gsonProvider;
    19  - private IBurpExtenderCallbacks callbacks;
    20 15   private Level logLevel;
    21 16   
    22  - public LoggingController(IGsonProvider gsonProvider) {
     17 + public LoggingController(IGsonProvider gsonProvider, MontoyaApi montoyaApi) {
    23 18   this.gsonProvider = gsonProvider;
    24  - this.callbacks = LoggerPlusPlus.callbacks;
    25  - configureLogger();
    26  - }
    27  - 
    28  - private void configureLogger() {
    29  - logLevel = gsonProvider.getGson().fromJson(callbacks.loadExtensionSetting(Globals.PREF_LOG_LEVEL), Level.class);
    30  - 
    31  - if (logLevel == null) { //Handle change from debug boolean to log level.
    32  - logLevel = Level.INFO;
    33  - callbacks.saveExtensionSetting(Globals.PREF_LOG_LEVEL, gsonProvider.getGson().toJson(logLevel));
    34  - }
    35  - 
    36  - LoggerContext context = (LoggerContext) LogManager.getContext(false);
    37  - Configuration config = context.getConfiguration();
    38  - PatternLayout logLayout = PatternLayout.newBuilder()
    39  - .withConfiguration(config)
    40  - .withPattern("[%-5level] %d{yyyy-MM-dd HH:mm:ss} %msg%n")
    41  - .build();
    42  - 
    43  - Appender burpAppender = new AbstractAppender("Burp Appender", null, logLayout, false, null) {
    44  - @Override
    45  - public void append(LogEvent event) {
    46  - String message = new String(this.getLayout().toByteArray(event));
    47  - if (event.getLevel().isMoreSpecificThan(Level.INFO)) {
    48  - callbacks.printError(message);
    49  - } else {
    50  - callbacks.printOutput(message);
    51  - }
    52  - }
    53  - };
    54  - burpAppender.start();
    55  - 
    56  - context.getConfiguration().getRootLogger().addAppender(burpAppender, logLevel, null);
    57  - context.updateLoggers();
     19 + logLevel = gsonProvider.getGson().fromJson(montoyaApi.persistence().preferences().getString(Globals.PREF_LOG_LEVEL), Level.class);
     20 + setLogLevel(logLevel);
    58 21   }
    59 22   
    60 23   public void setLogLevel(Level logLevel) {
    skipped 7 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/logview/LogViewController.java
    skipped 6 lines
    7 7  import com.nccgroup.loggerplusplus.filterlibrary.FilterLibraryController;
    8 8  import com.nccgroup.loggerplusplus.logview.entryviewer.RequestViewerController;
    9 9  import com.nccgroup.loggerplusplus.logview.logtable.LogTableController;
     10 +import lombok.Getter;
    10 11   
    11 12  public class LogViewController {
    12 13   
    13  - private final LoggerPlusPlus loggerPlusPlus;
     14 + @Getter
    14 15   private final FilterLibraryController filterLibraryController;
     16 + 
     17 + @Getter
    15 18   private final Preferences preferences;
     19 + 
     20 + @Getter
    16 21   private final LogFilterController logFilterController;
     22 + 
     23 + @Getter
    17 24   private final LogTableController logTableController;
     25 + 
     26 + @Getter
    18 27   private final RequestViewerController requestViewerController;
    19 28   
     29 + @Getter
    20 30   private final LogViewPanel logViewPanel;
    21 31   
    22  - public LogViewController(LoggerPlusPlus loggerPlusPlus, FilterLibraryController filterLibraryController){
    23  - this.loggerPlusPlus = loggerPlusPlus;
     32 + public LogViewController(FilterLibraryController filterLibraryController){
    24 33   this.filterLibraryController = filterLibraryController;
    25  - this.preferences = loggerPlusPlus.getPreferencesController().getPreferences();
     34 + this.preferences = LoggerPlusPlus.instance.getPreferencesController().getPreferences();
    26 35   
    27 36   this.logTableController = new LogTableController(this, filterLibraryController);
    28 37   this.logFilterController = new LogFilterController(this);
    29  - this.requestViewerController = new RequestViewerController(preferences, false, false);
     38 + this.requestViewerController = new RequestViewerController(preferences);
    30 39   
    31 40   //Build UI
    32 41   this.logViewPanel = new LogViewPanel(this);
    skipped 5 lines
    38 47   
    39 48   public void setEntryViewerLayout(VariableViewPanel.View view){
    40 49   this.logViewPanel.getRequestViewerPanel().getVariableViewPanel().setView(view);
    41  - }
    42  - 
    43  - public LoggerPlusPlus getLoggerPlusPlus() {
    44  - return loggerPlusPlus;
    45  - }
    46  - 
    47  - public LogViewPanel getLogViewPanel() {
    48  - return logViewPanel;
    49  - }
    50  - 
    51  - public LogFilterController getLogFilterController() {
    52  - return logFilterController;
    53  - }
    54  - 
    55  - public LogTableController getLogTableController() {
    56  - return logTableController;
    57  - }
    58  - 
    59  - public RequestViewerController getRequestViewerController() {
    60  - return requestViewerController;
    61  - }
    62  - 
    63  - public Preferences getPreferences() {
    64  - return preferences;
    65 50   }
    66 51  }
    67 52   
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/logview/MultipleLogEntryMenu.java
    1 1  package com.nccgroup.loggerplusplus.logview;
    2 2   
     3 +import burp.api.montoya.core.BurpSuiteEdition;
     4 +import burp.api.montoya.http.message.HttpRequestResponse;
     5 +import burp.api.montoya.http.message.requests.HttpRequest;
     6 +import burp.api.montoya.scanner.AuditConfiguration;
     7 +import burp.api.montoya.scanner.BuiltInAuditConfiguration;
     8 +import burp.api.montoya.scanner.Crawl;
     9 +import burp.api.montoya.scanner.CrawlConfiguration;
     10 +import burp.api.montoya.scanner.audit.Audit;
    3 11  import com.nccgroup.loggerplusplus.LoggerPlusPlus;
    4 12  import com.nccgroup.loggerplusplus.exports.ContextMenuExportProvider;
    5 13  import com.nccgroup.loggerplusplus.exports.ExportController;
    skipped 1 lines
    7 15  import com.nccgroup.loggerplusplus.logentry.LogEntry;
    8 16  import com.nccgroup.loggerplusplus.logview.logtable.LogTable;
    9 17  import com.nccgroup.loggerplusplus.logview.logtable.LogTableController;
     18 +import lombok.extern.log4j.Log4j2;
    10 19   
    11 20  import javax.swing.*;
    12 21  import java.awt.datatransfer.Clipboard;
    skipped 8 lines
    21 30  /**
    22 31   * Created by corey on 24/08/17.
    23 32   */
     33 +@Log4j2
    24 34  public class MultipleLogEntryMenu extends JPopupMenu {
    25 35   
    26 36   public MultipleLogEntryMenu(final LogTableController logTableController, final List<LogEntry> selectedEntries){
    27 37   final LogTable logTable = logTableController.getLogTable();
    28  - final boolean isPro = LoggerPlusPlus.callbacks.getBurpVersion()[0].equals("Burp Suite Professional");
     38 + final boolean isPro = LoggerPlusPlus.montoya.burpSuite().version().edition() == BurpSuiteEdition.PROFESSIONAL;
    29 39   
    30 40   this.add(new JMenuItem(selectedEntries.size() + " items"));
    31 41   this.add(new Separator());
    skipped 44 lines
    76 86   this.add(copySelectedUrls);
    77 87   
    78 88   JMenu exportMenu = new JMenu("Export entries as...");
    79  - ExportController exportController = logTableController.getLogViewController().getLoggerPlusPlus().getExportController();
     89 + ExportController exportController = LoggerPlusPlus.instance.getExportController();
    80 90   for (LogExporter exporter : exportController.getExporters().values()) {
    81 91   if (exporter instanceof ContextMenuExportProvider) {
    82 92   JMenuItem item = ((ContextMenuExportProvider) exporter).getExportEntriesMenuItem(selectedEntries);
    skipped 8 lines
    91 101   
    92 102   this.add(new Separator());
    93 103   
    94  - JMenuItem spider = new JMenuItem(new AbstractAction("Spider selected " + selectedEntries.size() + " urls") {
     104 + JMenuItem scanner = new JMenuItem(new AbstractAction("Crawl selected " + selectedEntries.size() + " urls") {
    95 105   @Override
    96 106   public void actionPerformed(ActionEvent actionEvent) {
    97  - for (LogEntry entry : selectedEntries) {
    98  - LoggerPlusPlus.callbacks.sendToSpider(entry.getUrl());
    99  - }
     107 + List<String> urls = selectedEntries.stream().map(logEntry -> logEntry.getUrl().toExternalForm()).toList();
     108 + CrawlConfiguration config = CrawlConfiguration.crawlConfiguration(urls.toArray(String[]::new));
     109 + Crawl crawl = LoggerPlusPlus.montoya.scanner().startCrawl(config);
    100 110   }
    101 111   });
    102  - this.add(spider);
     112 + this.add(scanner);
    103 113   
    104 114   JMenuItem activeScan = new JMenuItem(new AbstractAction("Active scan selected " + selectedEntries.size() + " urls") {
    105 115   @Override
    106 116   public void actionPerformed(ActionEvent actionEvent) {
    107  - for (LogEntry entry : selectedEntries) {
    108  - LoggerPlusPlus.callbacks.doActiveScan(entry.getHostname(), entry.getTargetPort(), entry.isSSL(), entry.getRequest());
     117 + AuditConfiguration auditConfiguration = AuditConfiguration.auditConfiguration(BuiltInAuditConfiguration.LEGACY_ACTIVE_AUDIT_CHECKS);
     118 + Audit scan = LoggerPlusPlus.montoya.scanner().startAudit(auditConfiguration);
     119 + for (LogEntry selectedEntry : selectedEntries) {
     120 + scan.addRequestResponse(HttpRequestResponse.httpRequestResponse(selectedEntry.getRequest(), selectedEntry.getResponse()));
    109 121   }
    110 122   }
    111 123   });
    skipped 3 lines
    115 127   JMenuItem passiveScan = new JMenuItem(new AbstractAction("Passive scan selected " + selectedEntries.size() + " urls") {
    116 128   @Override
    117 129   public void actionPerformed(ActionEvent actionEvent) {
    118  - for (LogEntry entry : selectedEntries) {
    119  - if (entry.isComplete()) { //Cannot scan entries without response
    120  - LoggerPlusPlus.callbacks.doPassiveScan(entry.getHostname(), entry.getTargetPort(), entry.isSSL(), entry.getRequest(), entry.getResponse());
    121  - }
     130 + AuditConfiguration auditConfiguration = AuditConfiguration.auditConfiguration(BuiltInAuditConfiguration.LEGACY_PASSIVE_AUDIT_CHECKS);
     131 + Audit scan = LoggerPlusPlus.montoya.scanner().startAudit(auditConfiguration);
     132 + for (LogEntry selectedEntry : selectedEntries) {
     133 + scan.addRequestResponse(HttpRequestResponse.httpRequestResponse(selectedEntry.getRequest(), selectedEntry.getResponse()));
    122 134   }
    123 135   }
    124 136   });
    skipped 6 lines
    131 143   @Override
    132 144   public void actionPerformed(ActionEvent actionEvent) {
    133 145   for (LogEntry entry : selectedEntries) {
    134  - LoggerPlusPlus.callbacks.sendToRepeater(entry.getHostname(), entry.getTargetPort(), entry.isSSL(), entry.getRequest(), "L++");
     146 + LoggerPlusPlus.montoya.repeater().sendToRepeater(entry.getRequest());
    135 147   }
    136 148   }
    137 149   });
    skipped 3 lines
    141 153   @Override
    142 154   public void actionPerformed(ActionEvent actionEvent) {
    143 155   for (LogEntry entry : selectedEntries) {
    144  - LoggerPlusPlus.callbacks.sendToIntruder(entry.getHostname(), entry.getTargetPort(), entry.isSSL(), entry.getRequest());
     156 + LoggerPlusPlus.montoya.intruder().sendToIntruder(entry.getRequest());
    145 157   }
    146 158   }
    147 159   });
    skipped 4 lines
    152 164   @Override
    153 165   public void actionPerformed(ActionEvent actionEvent) {
    154 166   for (LogEntry entry : selectedEntries) {
    155  - LoggerPlusPlus.callbacks.sendToComparer(entry.getRequest());
     167 + LoggerPlusPlus.montoya.comparer().sendToComparer(entry.getRequest().toByteArray());
    156 168   }
    157 169   }
    158 170   });
    skipped 3 lines
    162 174   public void actionPerformed(ActionEvent actionEvent) {
    163 175   for (LogEntry entry : selectedEntries) {
    164 176   if (entry.isComplete()) { //Do not add entries without a response
    165  - LoggerPlusPlus.callbacks.sendToComparer(entry.getResponse());
     177 + LoggerPlusPlus.montoya.comparer().sendToComparer(entry.getResponse().toByteArray());
    166 178   }
    167 179   }
    168 180   }
    skipped 24 lines
    193 205   for (LogEntry item : items) {
    194 206   switch (scope) {
    195 207   case URL:
    196  - values.add(String.valueOf(item.getUrl()));
     208 + values.add(String.valueOf(item.getUrlString()));
    197 209   break;
    198 210   case PATH:
    199 211   values.add(item.getUrl().getPath());
    skipped 12 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/logview/SingleLogEntryMenu.java
    1 1  package com.nccgroup.loggerplusplus.logview;
    2 2   
     3 +import burp.api.montoya.core.BurpSuiteEdition;
     4 +import burp.api.montoya.http.message.HttpRequestResponse;
     5 +import burp.api.montoya.scanner.AuditConfiguration;
     6 +import burp.api.montoya.scanner.BuiltInAuditConfiguration;
     7 +import burp.api.montoya.scanner.Crawl;
     8 +import burp.api.montoya.scanner.CrawlConfiguration;
     9 +import burp.api.montoya.scanner.audit.Audit;
    3 10  import com.nccgroup.loggerplusplus.LoggerPlusPlus;
    4 11  import com.nccgroup.loggerplusplus.exports.ContextMenuExportProvider;
    5 12  import com.nccgroup.loggerplusplus.exports.ExportController;
    6 13  import com.nccgroup.loggerplusplus.exports.LogExporter;
    7 14  import com.nccgroup.loggerplusplus.filter.ComparisonOperator;
     15 +import com.nccgroup.loggerplusplus.filter.FilterExpression;
    8 16  import com.nccgroup.loggerplusplus.filter.LogicalOperator;
    9  -import com.nccgroup.loggerplusplus.filter.colorfilter.ColorFilter;
    10  -import com.nccgroup.loggerplusplus.filter.logfilter.LogFilter;
     17 +import com.nccgroup.loggerplusplus.filter.colorfilter.TableColorRule;
     18 +import com.nccgroup.loggerplusplus.filter.logfilter.LogTableFilter;
    11 19  import com.nccgroup.loggerplusplus.filter.parser.ParseException;
    12 20  import com.nccgroup.loggerplusplus.logentry.LogEntry;
    13 21  import com.nccgroup.loggerplusplus.logentry.LogEntryField;
    skipped 1 lines
    15 23  import com.nccgroup.loggerplusplus.logview.logtable.LogTableController;
    16 24  import com.nccgroup.loggerplusplus.logview.processor.LogProcessor;
    17 25  import com.nccgroup.loggerplusplus.util.userinterface.dialog.ColorFilterDialog;
     26 +import lombok.extern.log4j.Log4j2;
    18 27   
    19 28  import javax.swing.*;
    20 29  import java.awt.event.ActionEvent;
    skipped 5 lines
    26 35  /**
    27 36   * Created by corey on 24/08/17.
    28 37   */
     38 +@Log4j2
    29 39  public class SingleLogEntryMenu extends JPopupMenu {
    30 40   
    31  - public SingleLogEntryMenu(final LogTableController logTableController, final LogEntry entry, final LogEntryField selectedField){
     41 + public SingleLogEntryMenu(final LogTableController logTableController, final LogEntry entry, final LogEntryField selectedField) {
    32 42   final LogTable logTable = logTableController.getLogTable();
    33 43   final String columnName = selectedField.getFullLabel();
    34 44   final Object columnValue = entry.getValueByKey(selectedField);
    35 45   final String columnValueString;
    36 46   
    37  - if(columnValue != null){
    38  - if(columnValue instanceof Date){
     47 + if (columnValue != null) {
     48 + if (columnValue instanceof Date) {
    39 49   columnValueString = "\"" + LogProcessor.LOGGER_DATE_FORMAT.format(columnValue) + "\"";
    40  - }else {
     50 + } else {
    41 51   columnValueString = columnValue instanceof Number ?
    42 52   columnValue.toString() : "\"" + columnValue + "\"";
    43 53   }
    44  - }else{
     54 + } else {
    45 55   columnValueString = "\"\"";
    46 56   }
    47 57   
    48  - final boolean isPro = LoggerPlusPlus.callbacks.getBurpVersion()[0].equals("Burp Suite Professional");
     58 + final boolean isPro = LoggerPlusPlus.montoya.burpSuite().version().edition() == BurpSuiteEdition.PROFESSIONAL;
    49 59   String title = entry.getValueByKey(LogEntryField.URL).toString();
    50  - if(title.length() > 50) title = title.substring(0, 47) + "...";
     60 + if (title.length() > 50) title = title.substring(0, 47) + "...";
    51 61   this.add(new JMenuItem(title));
    52 62   this.add(new JPopupMenu.Separator());
    53 63   
    54  - if(selectedField != LogEntryField.NUMBER) {
     64 + if (selectedField != LogEntryField.NUMBER) {
    55 65   JMenuItem useAsFilter = new JMenuItem(new AbstractAction("Use " + columnName + " Value As LogFilter") {
    56 66   @Override
    57 67   public void actionPerformed(ActionEvent actionEvent) {
    skipped 7 lines
    65 75   JMenuItem andFilter = new JMenuItem(new AbstractAction(LogicalOperator.AND.getLabel()) {
    66 76   @Override
    67 77   public void actionPerformed(ActionEvent actionEvent) {
    68  - String newFilter = logTable.getCurrentFilter().addConditionToFilter(LogicalOperator.AND, selectedField, ComparisonOperator.EQUAL, columnValueString);
    69  - logTableController.getLogViewController().getLogFilterController().setFilter(newFilter);
     78 + try {
     79 + logTable.getCurrentFilter().getFilterExpression().addConditionToFilter(LogicalOperator.AND, selectedField, ComparisonOperator.EQUAL, columnValueString);
     80 + logTableController.getLogViewController().getLogFilterController().setFilter(logTable.getCurrentFilter());
     81 + } catch (ParseException e) {
     82 + throw new RuntimeException(e);
     83 + }
    70 84   }
    71 85   });
    72 86   
    73 87   JMenuItem andNotFilter = new JMenuItem(new AbstractAction("AND NOT") {
    74 88   @Override
    75 89   public void actionPerformed(ActionEvent actionEvent) {
    76  - String newFilter = logTable.getCurrentFilter().addConditionToFilter(LogicalOperator.AND, selectedField, ComparisonOperator.NOT_EQUAL, columnValueString);
    77  - logTableController.getLogViewController().getLogFilterController().setFilter(newFilter);
     90 + try {
     91 + logTable.getCurrentFilter().getFilterExpression().addConditionToFilter(LogicalOperator.AND, selectedField, ComparisonOperator.NOT_EQUAL, columnValueString);
     92 + logTableController.getLogViewController().getLogFilterController().setFilter(logTable.getCurrentFilter());
     93 + } catch (ParseException e) {
     94 + throw new RuntimeException(e);
     95 + }
    78 96   }
    79 97   });
    80 98   
    81 99   JMenuItem orFilter = new JMenuItem(new AbstractAction(LogicalOperator.OR.getLabel()) {
    82 100   @Override
    83 101   public void actionPerformed(ActionEvent actionEvent) {
    84  - String newFilter = logTable.getCurrentFilter().addConditionToFilter(LogicalOperator.OR, selectedField, ComparisonOperator.EQUAL, columnValueString);
    85  - logTableController.getLogViewController().getLogFilterController().setFilter(newFilter);
     102 + try {
     103 + logTable.getCurrentFilter().getFilterExpression().addConditionToFilter(LogicalOperator.OR, selectedField, ComparisonOperator.EQUAL, columnValueString);
     104 + logTableController.getLogViewController().getLogFilterController().setFilter(logTable.getCurrentFilter());
     105 + } catch (ParseException e) {
     106 + throw new RuntimeException(e);
     107 + }
    86 108   }
    87 109   });
    88 110   addToCurrentFilter.add(andFilter);
    skipped 5 lines
    94 116   JMenuItem colorFilterItem = new JMenuItem(new AbstractAction("Set " + columnName + " Value as Color Filter") {
    95 117   @Override
    96 118   public void actionPerformed(ActionEvent actionEvent) {
    97  - try {
    98  - ColorFilter colorFilter = new ColorFilter();
    99  - colorFilter.setFilter(new LogFilter(LoggerPlusPlus.instance.getLibraryController(),
    100  - columnName + " == " + columnValueString));
    101  - logTableController.getLogViewController().getLoggerPlusPlus().getLibraryController().addColorFilter(colorFilter);
    102  - ColorFilterDialog colorFilterDialog = new ColorFilterDialog(LoggerPlusPlus.instance.getLibraryController());
    103  - colorFilterDialog.setVisible(true);
    104  - } catch (ParseException e1) {
    105  - return;
    106  - }
     119 + TableColorRule tableColorRule = new TableColorRule("New Filter", columnName + " == " + columnValueString);
     120 + LoggerPlusPlus.instance.getLibraryController().addColorFilter(tableColorRule);
     121 + ColorFilterDialog colorFilterDialog = new ColorFilterDialog(LoggerPlusPlus.instance.getLibraryController());
     122 + colorFilterDialog.setVisible(true);
    107 123   }
    108 124   });
    109 125   this.add(colorFilterItem);
    110 126   }
    111 127   
    112 128   this.add(new JPopupMenu.Separator());
    113  - final boolean inScope = LoggerPlusPlus.callbacks.isInScope(entry.getUrl());
     129 + final boolean inScope = LoggerPlusPlus.isUrlInScope(entry.getUrlString());
    114 130   JMenuItem scopeItem;
    115  - if(!inScope){
     131 + if (!inScope) {
    116 132   scopeItem = new JMenu("Add to scope");
    117 133   scopeItem.add(new JMenuItem(new AbstractAction("Domain") {
    118 134   @Override
    119 135   public void actionPerformed(ActionEvent actionEvent) {
    120 136   try {
    121 137   URL domainURL = new URL(entry.getProtocol(), entry.getHostname(), entry.getTargetPort(), "");
    122  - LoggerPlusPlus.callbacks.includeInScope(domainURL);
     138 + LoggerPlusPlus.montoya.scope().includeInScope(domainURL.toExternalForm());
    123 139   } catch (MalformedURLException e) {
    124 140   JOptionPane.showMessageDialog(scopeItem, "Could not build URL for scope entry. Sorry!", "Add to scope", JOptionPane.ERROR_MESSAGE);
    125 141   }
    skipped 2 lines
    128 144   scopeItem.add(new JMenuItem(new AbstractAction("Domain + Path") {
    129 145   @Override
    130 146   public void actionPerformed(ActionEvent actionEvent) {
    131  - LoggerPlusPlus.callbacks.includeInScope(entry.getUrl());
     147 + LoggerPlusPlus.montoya.scope().isInScope(entry.getUrlString());
    132 148   }
    133 149   }));
    134  - }else{
     150 + } else {
    135 151   scopeItem = new JMenuItem(new AbstractAction("Remove from scope") {
    136 152   @Override
    137 153   public void actionPerformed(ActionEvent actionEvent) {
    138  - LoggerPlusPlus.callbacks.excludeFromScope(entry.getUrl());
     154 + LoggerPlusPlus.montoya.scope().excludeFromScope(entry.getUrlString());
    139 155   }
    140 156   });
    141 157   }
    142 158   this.add(scopeItem);
    143 159   
    144 160   JMenu exportMenu = new JMenu("Export as...");
    145  - ExportController exportController = logTableController.getLogViewController().getLoggerPlusPlus().getExportController();
     161 + ExportController exportController = LoggerPlusPlus.instance.getExportController();
    146 162   for (LogExporter exporter : exportController.getExporters().values()) {
    147 163   if (exporter instanceof ContextMenuExportProvider) {
    148 164   JMenuItem item = ((ContextMenuExportProvider) exporter).getExportEntriesMenuItem(Collections.singletonList(entry));
    skipped 1 lines
    150 166   }
    151 167   }
    152 168   
    153  - if(exportMenu.getItemCount() > 0){
     169 + if (exportMenu.getItemCount() > 0) {
    154 170   this.add(new JPopupMenu.Separator());
    155 171   this.add(exportMenu);
    156 172   }
    157 173   
    158 174   this.add(new JPopupMenu.Separator());
    159 175   
    160  - JMenuItem spider = new JMenuItem(new AbstractAction("Spider from here") {
     176 + JMenuItem spider = new JMenuItem(new AbstractAction("Crawl from here") {
    161 177   @Override
    162 178   public void actionPerformed(ActionEvent actionEvent) {
    163  - LoggerPlusPlus.callbacks.sendToSpider(entry.getUrl());
     179 + CrawlConfiguration config = CrawlConfiguration.crawlConfiguration(entry.getUrl().toExternalForm());
     180 + Crawl crawl = LoggerPlusPlus.montoya.scanner().startCrawl(config);
    164 181   }
    165 182   });
    166 183   this.add(spider);
    skipped 1 lines
    168 185   JMenuItem activeScan = new JMenuItem(new AbstractAction("Do an active scan") {
    169 186   @Override
    170 187   public void actionPerformed(ActionEvent actionEvent) {
    171  - LoggerPlusPlus.callbacks.doActiveScan(entry.getHostname(), entry.getTargetPort(), entry.isSSL(), entry.getRequest());
     188 + AuditConfiguration auditConfiguration = AuditConfiguration.auditConfiguration(BuiltInAuditConfiguration.LEGACY_ACTIVE_AUDIT_CHECKS);
     189 + Audit scan = LoggerPlusPlus.montoya.scanner().startAudit(auditConfiguration);
     190 + scan.addRequestResponse(HttpRequestResponse.httpRequestResponse(entry.getRequest(), entry.getResponse()));
    172 191   }
    173 192   });
    174 193   this.add(activeScan);
    skipped 2 lines
    177 196   JMenuItem passiveScan = new JMenuItem(new AbstractAction("Do a passive scan") {
    178 197   @Override
    179 198   public void actionPerformed(ActionEvent actionEvent) {
    180  - LoggerPlusPlus.callbacks.doPassiveScan(entry.getHostname(), entry.getTargetPort(), entry.isSSL(), entry.getRequest(), entry.getResponse());
     199 + AuditConfiguration auditConfiguration = AuditConfiguration.auditConfiguration(BuiltInAuditConfiguration.LEGACY_PASSIVE_AUDIT_CHECKS);
     200 + Audit scan = LoggerPlusPlus.montoya.scanner().startAudit(auditConfiguration);
     201 + scan.addRequestResponse(HttpRequestResponse.httpRequestResponse(entry.getRequest(), entry.getResponse()));
    181 202   }
    182 203   });
    183 204   passiveScan.setEnabled(entry.isComplete() && isPro);
    skipped 4 lines
    188 209   JMenuItem sendToRepeater = new JMenuItem(new AbstractAction("Send to Repeater") {
    189 210   @Override
    190 211   public void actionPerformed(ActionEvent actionEvent) {
    191  - LoggerPlusPlus.callbacks.sendToRepeater(entry.getHostname(), entry.getTargetPort(), entry.isSSL(), entry.getRequest(), "L++");
     212 + LoggerPlusPlus.montoya.repeater().sendToRepeater(entry.getRequest());
    192 213   }
    193 214   });
    194 215   this.add(sendToRepeater);
    skipped 1 lines
    196 217   JMenuItem sendToIntruder = new JMenuItem(new AbstractAction("Send to Intruder") {
    197 218   @Override
    198 219   public void actionPerformed(ActionEvent actionEvent) {
    199  - LoggerPlusPlus.callbacks.sendToIntruder(entry.getHostname(), entry.getTargetPort(), entry.isSSL(), entry.getRequest());
     220 + LoggerPlusPlus.montoya.intruder().sendToIntruder(entry.getRequest());
    200 221   }
    201 222   });
    202 223   this.add(sendToIntruder);
    skipped 2 lines
    205 226   JMenuItem comparerRequest = new JMenuItem(new AbstractAction("Request") {
    206 227   @Override
    207 228   public void actionPerformed(ActionEvent actionEvent) {
    208  - LoggerPlusPlus.callbacks.sendToComparer(entry.getRequest());
     229 + LoggerPlusPlus.montoya.comparer().sendToComparer(entry.getRequest().toByteArray());
    209 230   }
    210 231   });
    211 232   sendToComparer.add(comparerRequest);
    212 233   JMenuItem comparerResponse = new JMenuItem(new AbstractAction("Response") {
    213 234   @Override
    214 235   public void actionPerformed(ActionEvent actionEvent) {
    215  - LoggerPlusPlus.callbacks.sendToComparer(entry.getResponse());
     236 + LoggerPlusPlus.montoya.comparer().sendToComparer(entry.getResponse().toByteArray());
    216 237   }
    217 238   });
    218 239   sendToComparer.add(comparerResponse);
    skipped 14 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/logview/entryviewer/RequestViewerController.java
    1 1  package com.nccgroup.loggerplusplus.logview.entryviewer;
    2 2   
    3  -import burp.IHttpService;
    4  -import burp.IMessageEditor;
    5  -import burp.IMessageEditorController;
     3 +import burp.api.montoya.ui.editor.EditorOptions;
     4 +import burp.api.montoya.ui.editor.HttpRequestEditor;
     5 +import burp.api.montoya.ui.editor.HttpResponseEditor;
    6 6  import com.coreyd97.BurpExtenderUtilities.Preferences;
    7 7  import com.nccgroup.loggerplusplus.LoggerPlusPlus;
    8 8  import com.nccgroup.loggerplusplus.logentry.LogEntry;
     9 +import lombok.Getter;
    9 10   
    10  -public class RequestViewerController implements IMessageEditorController {
     11 +@Getter
     12 +public class RequestViewerController {
    11 13   
    12 14   private final Preferences preferences;
    13  - private final IMessageEditor requestEditor;
    14  - private final IMessageEditor responseEditor;
     15 + private final HttpRequestEditor requestEditor;
     16 + private final HttpResponseEditor responseEditor;
    15 17   private final RequestViewerPanel requestViewerPanel;
    16 18   
    17 19   private LogEntry currentEntry;
    18 20   
    19  - public RequestViewerController(Preferences preferences, boolean requestEditable, boolean responseEditable) {
     21 + public RequestViewerController(Preferences preferences) {
    20 22   this.preferences = preferences;
    21  - this.requestEditor = LoggerPlusPlus.callbacks.createMessageEditor(this, requestEditable);
    22  - this.responseEditor = LoggerPlusPlus.callbacks.createMessageEditor(this, responseEditable);
     23 + this.requestEditor = LoggerPlusPlus.montoya.userInterface().createHttpRequestEditor(EditorOptions.READ_ONLY);
     24 + this.responseEditor = LoggerPlusPlus.montoya.userInterface().createHttpResponseEditor(EditorOptions.READ_ONLY);
    23 25   this.requestViewerPanel = new RequestViewerPanel(this);
    24 26   }
    25 27   
    skipped 3 lines
    29 31   
    30 32   this.currentEntry = logEntry;
    31 33   
    32  - if (logEntry == null) {
    33  - requestEditor.setMessage(new byte[0], true);
    34  - responseEditor.setMessage(new byte[0], false);
    35  - return;
    36  - }
    37  - 
    38  - if (logEntry.getRequest() != null) {
    39  - requestEditor.setMessage(logEntry.getRequest(), true);
    40  - } else {
    41  - requestEditor.setMessage(new byte[0], true);
     34 + if (logEntry == null || logEntry.getRequest() == null) {
     35 + requestEditor.setRequest(null);
     36 + }else{
     37 + requestEditor.setRequest(logEntry.getRequest());
    42 38   }
    43 39   
    44  - if (logEntry.getResponse() != null) {
    45  - responseEditor.setMessage(logEntry.getResponse(), false);
    46  - } else {
    47  - responseEditor.setMessage(new byte[0], false);
    48  - }
    49  - }
    50  - 
    51  - public IMessageEditor getRequestEditor() {
    52  - return requestEditor;
    53  - }
    54  - 
    55  - public IMessageEditor getResponseEditor() {
    56  - return responseEditor;
    57  - }
    58  - 
    59  - public Preferences getPreferences() {
    60  - return preferences;
    61  - }
    62  - 
    63  - public RequestViewerPanel getRequestViewerPanel() {
    64  - return requestViewerPanel;
    65  - }
    66  - 
    67  - @Override
    68  - public byte[] getRequest() {
    69  - if (currentEntry != null && currentEntry.getRequest() != null) {
    70  - return currentEntry.getRequest();
    71  - } else {
    72  - return new byte[0];
     40 + if (logEntry == null || logEntry.getResponse() == null) {
     41 + responseEditor.setResponse(null);
     42 + }else{
     43 + responseEditor.setResponse(logEntry.getResponse());
    73 44   }
    74 45   }
    75 46   
    76  - @Override
    77  - public byte[] getResponse() {
    78  - if (currentEntry != null && currentEntry.getResponse() != null) {
    79  - return currentEntry.getResponse();
    80  - } else {
    81  - return new byte[0];
    82  - }
    83  - }
     47 + public void setMarkers(){
    84 48   
    85  - @Override
    86  - public IHttpService getHttpService() {
    87  - if (currentEntry == null) return null;
    88  - return currentEntry.getHttpService();
    89 49   }
    90 50  }
    91 51   
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/logview/entryviewer/RequestViewerPanel.java
    skipped 13 lines
    14 14   this.controller = controller;
    15 15   
    16 16   this.variableViewPanel = new VariableViewPanel(controller.getPreferences(), Globals.PREF_MESSAGE_VIEW_LAYOUT,
    17  - controller.getRequestEditor().getComponent(), "Request",
    18  - controller.getResponseEditor().getComponent(), "Response",
     17 + controller.getRequestEditor().uiComponent(), "Request",
     18 + controller.getResponseEditor().uiComponent(), "Response",
    19 19   VariableViewPanel.View.HORIZONTAL);
    20 20   
    21 21   this.setComponent(variableViewPanel);
    skipped 9 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/logview/logtable/LogTable.java
    skipped 4 lines
    5 5  //
    6 6   
    7 7  import com.coreyd97.BurpExtenderUtilities.Preferences;
    8  -import com.nccgroup.loggerplusplus.filter.colorfilter.ColorFilter;
    9  -import com.nccgroup.loggerplusplus.filter.logfilter.LogFilter;
     8 +import com.nccgroup.loggerplusplus.filter.colorfilter.TableColorRule;
     9 +import com.nccgroup.loggerplusplus.filter.logfilter.LogTableFilter;
    10 10  import com.nccgroup.loggerplusplus.logentry.LogEntry;
    11 11  import com.nccgroup.loggerplusplus.logentry.LogEntryField;
    12 12  import com.nccgroup.loggerplusplus.logview.MultipleLogEntryMenu;
    skipped 114 lines
    127 127   return c;
    128 128   }
    129 129   if(entry.getMatchingColorFilters().size() != 0){
    130  - ColorFilter colorFilter = null;
    131  - Map<UUID, ColorFilter> colorFilters = this.preferences.getSetting(Globals.PREF_COLOR_FILTERS);
     130 + TableColorRule tableColorRule = null;
     131 + Map<UUID, TableColorRule> colorFilters = this.preferences.getSetting(Globals.PREF_COLOR_FILTERS);
    132 132   for (UUID uid : entry.getMatchingColorFilters()) {
    133  - if(colorFilter == null || colorFilter.getPriority() > colorFilters.get(uid).getPriority()){
    134  - colorFilter = colorFilters.get(uid);
     133 + if(tableColorRule == null || tableColorRule.getPriority() > colorFilters.get(uid).getPriority()){
     134 + tableColorRule = colorFilters.get(uid);
    135 135   }
    136 136   }
    137  - if (colorFilter == null) {
     137 + if (tableColorRule == null) {
    138 138   c.setForeground(this.getForeground());
    139 139   c.setBackground(this.getBackground());
    140 140   } else {
    141  - c.setForeground(colorFilter.getForegroundColor());
    142  - c.setBackground(colorFilter.getBackgroundColor());
     141 + c.setForeground(tableColorRule.getForegroundColor());
     142 + c.setBackground(tableColorRule.getBackgroundColor());
    143 143   }
    144 144   }else{
    145 145   c.setForeground(this.getForeground());
    skipped 62 lines
    208 208   }
    209 209   
    210 210   
    211  - public LogFilter getCurrentFilter(){
    212  - return (LogFilter) this.sorter.getRowFilter();
     211 + public LogTableFilter getCurrentFilter(){
     212 + return (LogTableFilter) this.sorter.getRowFilter();
    213 213   }
    214 214   
    215  - public void setFilter(LogFilter filter){
     215 + public void setFilter(LogTableFilter filter){
    216 216   this.sorter.setRowFilter(filter);
    217 217   ((JScrollPane) this.getParent().getParent()).getVerticalScrollBar().setValue(0);
    218 218   }
    skipped 9 lines
  • ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/logview/logtable/LogTableColumn.java
    skipped 18 lines
    19 19   
    20 20  import com.google.gson.*;
    21 21  import com.nccgroup.loggerplusplus.logentry.LogEntryField;
    22  -import com.nccgroup.loggerplusplus.util.userinterface.renderer.LeftTableCellRenderer;
    23 22   
    24 23  import javax.swing.table.TableColumn;
    25 24  import java.lang.reflect.Type;
    skipped 118 lines
  • ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/logview/logtable/LogTableColumnModel.java
    skipped 15 lines
    16 16  import com.nccgroup.loggerplusplus.logentry.LogEntryField;
    17 17  import com.nccgroup.loggerplusplus.util.Globals;
    18 18  import com.nccgroup.loggerplusplus.LoggerPlusPlus;
     19 +import com.nccgroup.loggerplusplus.util.userinterface.renderer.TagRenderer;
    19 20   
    20 21  import javax.swing.event.TableColumnModelEvent;
     22 +import javax.swing.table.DefaultTableCellRenderer;
    21 23  import javax.swing.table.DefaultTableColumnModel;
    22 24  import javax.swing.table.TableColumn;
    23 25  import java.util.*;
    skipped 22 lines
    46 48   if (column.isVisible()) {
    47 49   addColumn(column);
    48 50   }
     51 + }
     52 + 
     53 + Optional<LogTableColumn> tagColumn = this.allColumns.stream().filter(logTableColumn -> logTableColumn.getName().equals("Tags")).findFirst();
     54 + if((boolean) preferences.getSetting(Globals.PREF_TABLE_PILL_STYLE) && tagColumn.isPresent()){
     55 + tagColumn.get().setCellRenderer(new TagRenderer());
    49 56   }
    50 57   
    51 58   initialize();
    skipped 116 lines
    168 175   }
    169 176   }
    170 177   
    171  - public Enumeration<LogTableColumn> getAllColumns() {
    172  - return Collections.enumeration(this.allColumns);
     178 + public List<LogTableColumn> getAllColumns() {
     179 + return this.allColumns;
    173 180   }
    174 181  }
    175 182   
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/logview/logtable/LogTableModel.java
    1 1  package com.nccgroup.loggerplusplus.logview.logtable;
    2 2   
    3  -import com.nccgroup.loggerplusplus.filter.colorfilter.ColorFilter;
     3 +import com.nccgroup.loggerplusplus.filter.colorfilter.TableColorRule;
    4 4  import com.nccgroup.loggerplusplus.filter.colorfilter.ColorFilterListener;
    5 5  import com.nccgroup.loggerplusplus.filter.tag.Tag;
    6 6  import com.nccgroup.loggerplusplus.filter.tag.TagListener;
    skipped 120 lines
    127 127   
    128 128   // FilterListeners
    129 129   @Override
    130  - public void onColorFilterChange(final ColorFilter filter) {
    131  - createFilterTestingWorker(filter, filter.shouldRetest()).execute();
     130 + public void onColorFilterChange(final TableColorRule filter) {
     131 + createFilterTestingWorker(filter, filter.isShouldRetest()).execute();
    132 132   }
    133 133   
    134 134   @Override
    135  - public void onColorFilterAdd(final ColorFilter filter) {
    136  - if (!filter.isEnabled() || filter.getFilter() == null)
     135 + public void onColorFilterAdd(final TableColorRule filter) {
     136 + if (!filter.isEnabled() || filter.getFilterExpression() == null)
    137 137   return;
    138 138   createFilterTestingWorker(filter, false);
    139 139   }
    140 140   
    141 141   @Override
    142  - public void onColorFilterRemove(final ColorFilter filter) {
    143  - if (!filter.isEnabled() || filter.getFilter() == null)
     142 + public void onColorFilterRemove(final TableColorRule filter) {
     143 + if (!filter.isEnabled() || filter.getFilterExpression() == null)
    144 144   return;
    145 145   new SwingWorker<Void, Integer>() {
    146 146   @Override
    147 147   protected Void doInBackground() {
    148 148   for (int i = 0; i < entries.size(); i++) {
    149  - boolean wasPresent = entries.get(i).getMatchingColorFilters().remove(filter.getUUID());
     149 + boolean wasPresent = entries.get(i).getMatchingColorFilters().remove(filter.getUuid());
    150 150   if (wasPresent) {
    151 151   publish(i);
    152 152   }
    skipped 10 lines
    163 163   }.execute();
    164 164   }
    165 165   
    166  - private SwingWorker<Void, Integer> createFilterTestingWorker(final ColorFilter filter, boolean retestExisting) {
     166 + private SwingWorker<Void, Integer> createFilterTestingWorker(final TableColorRule filter, boolean retestExisting) {
    167 167   return new SwingWorker<Void, Integer>() {
    168 168   
    169 169   @Override
    skipped 25 lines
    195 195   
    196 196   @Override
    197 197   public void onTagAdd(final Tag filter) {
    198  - if (!filter.isEnabled() || filter.getFilter() == null)
     198 + if (!filter.isEnabled() || filter.getFilterExpression() == null)
    199 199   return;
    200  - createTagTestingWorker(filter, false);
     200 + createTagTestingWorker(filter, false).execute();
    201 201   }
    202 202   
    203 203   @Override
    204 204   public void onTagRemove(final Tag filter) {
    205  - if (!filter.isEnabled() || filter.getFilter() == null)
     205 + if (!filter.isEnabled() || filter.getFilterExpression() == null)
    206 206   return;
    207 207   new SwingWorker<Void, Integer>() {
    208 208   @Override
    skipped 43 lines
  • ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/logview/logtable/TableHeader.java
    skipped 1 lines
    2 2   
    3 3  import javax.swing.*;
    4 4  import javax.swing.table.JTableHeader;
    5  -import javax.swing.table.TableColumnModel;
    6 5  import java.awt.*;
    7 6  import java.awt.event.MouseAdapter;
    8 7  import java.awt.event.MouseEvent;
    skipped 50 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/logview/logtable/TableHeaderMenu.java
    skipped 61 lines
    62 62   item = new JMenuItem("Make all visible");
    63 63   item.addActionListener(new ActionListener() {
    64 64   public void actionPerformed(ActionEvent e) {
    65  - Enumeration<LogTableColumn> columnEnumeration = logTable.getColumnModel().getAllColumns();
    66  - while (columnEnumeration.hasMoreElements()) {
    67  - LogTableColumn logTableColumn = columnEnumeration.nextElement();
    68  - logTable.getColumnModel().showColumn(logTableColumn);
     65 + for (LogTableColumn column : logTable.getColumnModel().getAllColumns()) {
     66 + logTable.getColumnModel().showColumn(column);
    69 67   }
    70 68   logTableController.getLogTableColumnModel().saveLayout();
    71 69   }
    skipped 2 lines
    74 72   
    75 73   Map<FieldGroup, JMenu> groupMenus = new HashMap<>();
    76 74   
    77  - Enumeration<LogTableColumn> columnEnumeration = logTable.getColumnModel().getAllColumns();
    78  - while (columnEnumeration.hasMoreElements()) {
    79  - LogTableColumn logTableColumn = columnEnumeration.nextElement();
     75 + for (LogTableColumn logTableColumn : logTable.getColumnModel().getAllColumns()) {
     76 + 
    80 77   FieldGroup group = logTableColumn.getIdentifier().getFieldGroup();
    81 78   if (!groupMenus.containsKey(group)) {
    82 79   groupMenus.put(group, new JMenu(group.getLabel()));
    skipped 27 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/logview/processor/EntryImportWorker.java
    1 1  package com.nccgroup.loggerplusplus.logview.processor;
    2 2   
    3  -import burp.IBurpExtenderCallbacks;
    4  -import burp.IHttpRequestResponse;
     3 +import burp.api.montoya.core.ToolType;
     4 +import burp.api.montoya.http.message.HttpRequestResponse;
     5 +import burp.api.montoya.http.message.requests.HttpRequest;
     6 +import burp.api.montoya.http.message.responses.HttpResponse;
     7 +import burp.api.montoya.proxy.ProxyHttpRequestResponse;
    5 8  import com.nccgroup.loggerplusplus.logentry.LogEntry;
    6 9   
    7 10  import javax.swing.*;
    skipped 5 lines
    13 16  public class EntryImportWorker extends SwingWorker<Void, Integer> {
    14 17   
    15 18   private final LogProcessor logProcessor;
    16  - private final int originatingTool;
    17  - private final List<IHttpRequestResponse> entries;
     19 + private final ToolType originatingTool;
     20 + private final List<ProxyHttpRequestResponse> proxyEntries;
     21 + private final List<HttpRequestResponse> httpEntries;
    18 22   private final Consumer<List<Integer>> interimConsumer;
    19 23   private final Runnable callback;
    20 24   private final boolean sendToAutoExporters;
    skipped 1 lines
    22 26   private EntryImportWorker(Builder builder){
    23 27   this.logProcessor = builder.logProcessor;
    24 28   this.originatingTool = builder.originatingTool;
    25  - this.entries = builder.entries;
     29 + this.proxyEntries = builder.proxyEntries;
     30 + this.httpEntries = builder.httpEntries;
    26 31   this.interimConsumer = builder.interimConsumer;
    27 32   this.callback = builder.callback;
    28 33   this.sendToAutoExporters = builder.sendToAutoExporters;
    skipped 2 lines
    31 36   @Override
    32 37   protected Void doInBackground() throws Exception {
    33 38   logProcessor.getEntryProcessExecutor().pause(); //Pause the processor, we don't want it mixing with our import.
     39 + boolean isProxyEntries = proxyEntries.size() > 0;
     40 + int count = isProxyEntries ? proxyEntries.size() : httpEntries.size();
     41 + 
    34 42   
    35  - CountDownLatch countDownLatch = new CountDownLatch(entries.size());
     43 + CountDownLatch countDownLatch = new CountDownLatch(count);
    36 44   ThreadPoolExecutor entryImportExecutor = logProcessor.getEntryImportExecutor();
    37  - for (int index = 0; index < entries.size(); index++) {
     45 + for (int index = 0; index < count; index++) {
    38 46   if(entryImportExecutor.isShutdown() || this.isCancelled()) return null;
    39  - final LogEntry logEntry = new LogEntry(originatingTool, entries.get(index));
     47 + HttpRequest request;
     48 + HttpResponse response;
     49 + if(isProxyEntries){
     50 + request = proxyEntries.get(index).finalRequest();
     51 + response = proxyEntries.get(index).originalResponse();
     52 + }else{
     53 + request = httpEntries.get(index).request();
     54 + response = httpEntries.get(index).response();
     55 + }
     56 + final LogEntry logEntry = new LogEntry(originatingTool, request, response);
    40 57   int finalIndex = index;
    41 58   entryImportExecutor.submit(() -> {
    42 59   if(this.isCancelled()) return;
    skipped 25 lines
    68 85   public static class Builder {
    69 86   
    70 87   private final LogProcessor logProcessor;
    71  - private int originatingTool = IBurpExtenderCallbacks.TOOL_EXTENDER;
    72  - private List<IHttpRequestResponse> entries;
     88 + private ToolType originatingTool = ToolType.EXTENSIONS;
     89 + private List<ProxyHttpRequestResponse> proxyEntries;
     90 + private List<HttpRequestResponse> httpEntries;
    73 91   private Consumer<List<Integer>> interimConsumer;
    74 92   private Runnable callback;
    75 93   private boolean sendToAutoExporters = false;
    skipped 2 lines
    78 96   this.logProcessor = logProcessor;
    79 97   }
    80 98   
    81  - public Builder setOriginatingTool(int originatingTool){
     99 + public Builder setOriginatingTool(ToolType originatingTool){
    82 100   this.originatingTool = originatingTool;
    83 101   return this;
    84 102   }
    85 103   
    86  - public Builder setEntries(List<IHttpRequestResponse> entries) {
    87  - this.entries = entries;
     104 + public Builder setProxyEntries(List<ProxyHttpRequestResponse> entries) {
     105 + this.proxyEntries.addAll(entries);
     106 + this.httpEntries.clear();
     107 + return this;
     108 + }
     109 + 
     110 + public Builder setHttpEntries(List<HttpRequestResponse> entries) {
     111 + this.httpEntries.addAll(entries);
     112 + this.proxyEntries.clear();
    88 113   return this;
    89 114   }
    90 115   
    skipped 22 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/logview/processor/LogProcessor.java
    1 1  package com.nccgroup.loggerplusplus.logview.processor;
    2 2   
    3  -import burp.*;
     3 +import burp.api.montoya.core.Annotations;
     4 +import burp.api.montoya.core.ToolType;
     5 +import burp.api.montoya.http.handler.*;
     6 +import burp.api.montoya.http.message.responses.HttpResponse;
     7 +import burp.api.montoya.proxy.ProxyHttpRequestResponse;
     8 +import burp.api.montoya.proxy.http.*;
    4 9  import com.coreyd97.BurpExtenderUtilities.Preferences;
    5 10  import com.nccgroup.loggerplusplus.LoggerPlusPlus;
    6 11  import com.nccgroup.loggerplusplus.exports.ExportController;
    7  -import com.nccgroup.loggerplusplus.filter.colorfilter.ColorFilter;
     12 +import com.nccgroup.loggerplusplus.filter.colorfilter.TableColorRule;
    8 13  import com.nccgroup.loggerplusplus.filter.tag.Tag;
    9 14  import com.nccgroup.loggerplusplus.logentry.LogEntry;
    10 15  import com.nccgroup.loggerplusplus.logentry.Status;
    11 16  import com.nccgroup.loggerplusplus.logview.logtable.LogTableController;
    12 17  import com.nccgroup.loggerplusplus.util.NamedThreadFactory;
    13 18  import com.nccgroup.loggerplusplus.util.PausableThreadPoolExecutor;
     19 +import lombok.Getter;
     20 +import lombok.extern.log4j.Log4j2;
    14 21  import org.apache.logging.log4j.LogManager;
    15 22  import org.apache.logging.log4j.Logger;
    16 23   
    skipped 7 lines
    24 31  /**
    25 32   * Created by corey on 07/09/17.
    26 33   */
    27  -public class LogProcessor implements IHttpListener, IProxyListener {
     34 +@Log4j2
     35 +public class LogProcessor {
    28 36   public static final SimpleDateFormat LOGGER_DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    29 37   public static final SimpleDateFormat SERVER_DATE_FORMAT = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz");
    30  - 
    31  - private final LoggerPlusPlus loggerPlusPlus;
    32 38   private final LogTableController logTableController;
    33 39   private final ExportController exportController;
    34 40   private final Preferences preferences;
    skipped 3 lines
    38 44   private final PausableThreadPoolExecutor entryImportExecutor;
    39 45   private final ScheduledExecutorService cleanupExecutor;
    40 46   
     47 + @Getter
     48 + private final HttpHandler httpHandler;
     49 + @Getter
     50 + private final ProxyResponseHandler proxyResponseHandler;
     51 + 
    41 52   Logger logger = LogManager.getLogger(this);
    42 53   
    43 54   /**
    skipped 1 lines
    45 56   * Logic to allow requests independently and match them to responses once received.
    46 57   * TODO SQLite integration
    47 58   */
    48  - public LogProcessor(LoggerPlusPlus loggerPlusPlus, LogTableController logTableController, ExportController exportController) {
    49  - this.loggerPlusPlus = loggerPlusPlus;
     59 + public LogProcessor(LogTableController logTableController, ExportController exportController) {
    50 60   this.logTableController = logTableController;
    51 61   this.exportController = exportController;
    52  - this.preferences = this.loggerPlusPlus.getPreferencesController().getPreferences();
     62 + this.preferences = LoggerPlusPlus.instance.getPreferencesController().getPreferences();
    53 63   
    54 64   this.entriesPendingProcessing = new ConcurrentHashMap<>();
    55 65   this.entryProcessingFutures = new ConcurrentHashMap<>();
    skipped 6 lines
    62 72   this.cleanupExecutor = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("LPP-LogManager-Cleanup"));
    63 73   this.cleanupExecutor.scheduleAtFixedRate(new AbandonedRequestCleanupRunnable(),30, 30, TimeUnit.SECONDS);
    64 74   
    65  - LoggerPlusPlus.callbacks.registerHttpListener(this);
    66  - LoggerPlusPlus.callbacks.registerProxyListener(this);
     75 + //TODO Enable new logging API when support for matching requests and their responses improves...
     76 + this.httpHandler = createHttpHandler();
     77 + this.proxyResponseHandler = createProxyResponseHandler();
    67 78   }
    68 79   
    69  - /**
    70  - * Process messages from all tools.
    71  - * Adds to queue for later processing.
    72  - * Note: processProxyMessage runs *after* processHttpMessage, responses from the proxy tool are left for that method.
    73  - *
    74  - * @param toolFlag Tool used to make request
    75  - * @param isRequestOnly If the message is request only or complete with response
    76  - * @param httpMessage The request and potentially response received.
    77  - */
    78  - @Override
    79  - public void processHttpMessage(final int toolFlag, final boolean isRequestOnly, final IHttpRequestResponse httpMessage) {
    80  - if (httpMessage == null || !(Boolean) preferences.getSetting(PREF_ENABLED) || !isValidTool(toolFlag)) return;
    81  - Date arrivalTime = new Date();
     80 + private HttpHandler createHttpHandler(){
     81 + return new HttpHandler() {
     82 + @Override
     83 + public RequestToBeSentAction handleHttpRequestToBeSent(HttpRequestToBeSent requestToBeSent) {
     84 + if (!(Boolean) preferences.getSetting(PREF_ENABLED) || !isValidTool(requestToBeSent.toolSource().toolType())
     85 + || !LoggerPlusPlus.isUrlInScope(requestToBeSent.url())){
     86 + return RequestToBeSentAction.continueWith(requestToBeSent);
     87 + }
     88 + Date arrivalTime = new Date();
     89 + 
     90 + //If we're handling a new request, create a log entry.
     91 + //We must also handle proxy messages here, since the HTTP listener operates after the proxy listener
     92 + final LogEntry logEntry = new LogEntry(requestToBeSent.toolSource().toolType(), requestToBeSent, arrivalTime);
     93 + 
     94 + //Set the entry's identifier to the HTTP request's hashcode.
     95 + // For non-proxy messages, this doesn't change when we receive the response
     96 + Integer identifier = System.identityHashCode(requestToBeSent);
     97 + 
     98 + logEntry.setIdentifier(identifier);
     99 + Annotations annotations = LogProcessorHelper.addIdentifierInComment(identifier, requestToBeSent.annotations());
     100 + //Submit a new task to process the entry
     101 + submitNewEntryProcessingRunnable(logEntry);
     102 + 
     103 + return RequestToBeSentAction.continueWith(requestToBeSent, annotations);
     104 + }
    82 105   
    83  - if (isRequestOnly) {
    84  - //If we're handling a new request, create a log entry.
    85  - //We must also handle proxy messages here, since the HTTP listener operates after the proxy listener
    86  - final LogEntry logEntry = new LogEntry(toolFlag, arrivalTime, httpMessage);
     106 + @Override
     107 + public ResponseReceivedAction handleHttpResponseReceived(HttpResponseReceived responseReceived) {
     108 + if (!(Boolean) preferences.getSetting(PREF_ENABLED) || !isValidTool(responseReceived.toolSource().toolType())
     109 + || !LoggerPlusPlus.isUrlInScope(responseReceived.initiatingRequest().url())){
     110 + return ResponseReceivedAction.continueWith(responseReceived);
     111 + }
     112 + Date arrivalTime = new Date();
    87 113   
    88  - //Set the entry's identifier to the HTTP request's hashcode.
    89  - // For non-proxy messages, this doesn't change when we receive the response
    90  - logEntry.setIdentifier(System.identityHashCode(httpMessage.getRequest()));
    91  - //Submit a new task to process the entry
    92  - submitNewEntryProcessingRunnable(logEntry);
    93  - } else {
    94  - if (toolFlag == IBurpExtenderCallbacks.TOOL_PROXY) {
    95  - //If the request came from the proxy, the response isn't final yet.
    96  - //Just tag the comment with the identifier so we can match it up later.
    97  - Integer identifier = System.identityHashCode(httpMessage.getRequest());
    98  - LogProcessorHelper.addIdentifierInComment(identifier, httpMessage);
    99  - return; //Process proxy responses using processProxyMessage
    100  - } else {
    101  - //Otherwise, we have the final HTTP response, and can use the request hashcode to match it up with the log entry.
    102  - Integer identifier = System.identityHashCode(httpMessage.getRequest());
    103  - updateRequestWithResponse(identifier, arrivalTime, httpMessage);
     114 + Annotations annotations = responseReceived.annotations();
     115 + if (responseReceived.toolSource().isFromTool(ToolType.PROXY)) {
     116 + //If the request came from the proxy, the response isn't final yet.
     117 + //Just tag the comment with the identifier so we can match it up later.
     118 +// Integer identifier = System.identityHashCode(responseReceived.initiatingRequest());
     119 +// annotations = LogProcessorHelper.addIdentifierInComment(identifier, annotations);
     120 +// return ResponseResult.responseResult(response, annotations); //Process proxy responses using processProxyMessage
     121 + } else {
     122 + //Otherwise, we have the final HTTP response, and can use the request hashcode to match it up with the log entry.
     123 + Object[] identifierAndAnnotation = LogProcessorHelper.extractAndRemoveIdentifierFromRequestResponseComment(responseReceived.annotations());
     124 + Integer identifier = (Integer) identifierAndAnnotation[0]; //TODO Ew.
     125 + annotations = (Annotations) identifierAndAnnotation[1];
     126 + updateRequestWithResponse(identifier, arrivalTime, responseReceived);
     127 + }
     128 + return ResponseReceivedAction.continueWith(responseReceived, annotations);
    104 129   }
    105  - }
     130 + };
    106 131   }
    107 132   
    108  - /**
    109  - * Since this method runs after processHttpMessage, we must use it to get the final response for proxy tool requests
    110  - * otherwise, changes to the message by other tools using processProxyMessage would not be seen!
    111  - *
    112  - * @param isRequestOnly
    113  - * @param proxyMessage
    114  - */
    115  - @Override
    116  - public void processProxyMessage(final boolean isRequestOnly, final IInterceptedProxyMessage proxyMessage) {
    117  - final int toolFlag = IBurpExtenderCallbacks.TOOL_PROXY;
    118  - if (proxyMessage == null || !(Boolean) preferences.getSetting(PREF_ENABLED) || !isValidTool(toolFlag)) return;
    119  - Date arrivalTime = new Date();
     133 + private ProxyResponseHandler createProxyResponseHandler(){
     134 + return new ProxyResponseHandler() {
     135 + @Override
     136 + public ProxyResponseReceivedAction handleResponseReceived(InterceptedResponse interceptedResponse) {
     137 + return ProxyResponseReceivedAction.continueWith(interceptedResponse); //Do nothing
     138 + }
     139 + 
     140 + @Override
     141 + public ProxyResponseToBeSentAction handleResponseToBeSent(InterceptedResponse interceptedResponse) {
     142 + if(!((boolean) preferences.getSetting(PREF_ENABLED)) || !((boolean) preferences.getSetting(PREF_LOG_PROXY))
     143 + || !LoggerPlusPlus.isUrlInScope(interceptedResponse.initiatingRequest().url())) {
     144 + return ProxyResponseToBeSentAction.continueWith(interceptedResponse);
     145 + }
    120 146   
    121  - if (isRequestOnly) {
     147 + Date arrivalTime = new Date();
     148 + Object[] identifierAndAnnotation = LogProcessorHelper.extractAndRemoveIdentifierFromRequestResponseComment(interceptedResponse.annotations());
     149 + Integer identifier = (Integer) identifierAndAnnotation[0]; //TODO Ew.
     150 + Annotations annotations = (Annotations) identifierAndAnnotation[1];
    122 151   
    123  - } else { //We only want to handle responses.
    124  - Integer identifier = LogProcessorHelper.extractAndRemoveIdentifierFromRequestResponseComment(proxyMessage.getMessageInfo());
    125  - updateRequestWithResponse(identifier, arrivalTime, proxyMessage.getMessageInfo());
    126  - }
     152 + updateRequestWithResponse(identifier, arrivalTime, interceptedResponse);
     153 + return ProxyResponseToBeSentAction.continueWith(interceptedResponse, annotations);
     154 + }
     155 + };
    127 156   }
    128 157   
     158 + 
     159 +// /**
     160 +// * Process messages from all tools.
     161 +// * Adds to queue for later processing.
     162 +// * Note: processProxyMessage runs *after* processHttpMessage, responses from the proxy tool are left for that method.
     163 +// *
     164 +// * @param toolFlag Tool used to make request
     165 +// * @param isRequestOnly If the message is request only or complete with response
     166 +// * @param httpMessage The request and potentially response received.
     167 +// */
     168 +// @Override
     169 +// public void processHttpMessage(final int toolFlag, final boolean isRequestOnly, final IHttpRequestResponse httpMessage) {
     170 +// if (httpMessage == null || !(Boolean) preferences.getSetting(PREF_ENABLED) || !isValidTool(toolFlag)) return;
     171 +// Date arrivalTime = new Date();
     172 +//
     173 +// if (isRequestOnly) {
     174 +// //If we're handling a new request, create a log entry.
     175 +// //We must also handle proxy messages here, since the HTTP listener operates after the proxy listener
     176 +// final LogEntry logEntry = new LogEntry(toolFlag, arrivalTime, httpMessage);
     177 +//
     178 +// //Set the entry's identifier to the HTTP request's hashcode.
     179 +// // For non-proxy messages, this doesn't change when we receive the response
     180 +// logEntry.setIdentifier(System.identityHashCode(httpMessage.getRequest()));
     181 +// //Submit a new task to process the entry
     182 +// submitNewEntryProcessingRunnable(logEntry);
     183 +// } else {
     184 +// if (toolFlag == IBurpExtendermontoya.TOOL_PROXY) {
     185 +// //If the request came from the proxy, the response isn't final yet.
     186 +// //Just tag the comment with the identifier so we can match it up later.
     187 +// Integer identifier = System.identityHashCode(httpMessage.getRequest());
     188 +// LogProcessorHelper.addIdentifierInComment(identifier, httpMessage);
     189 +// return; //Process proxy responses using processProxyMessage
     190 +// } else {
     191 +// //Otherwise, we have the final HTTP response, and can use the request hashcode to match it up with the log entry.
     192 +// Integer identifier = System.identityHashCode(httpMessage.getRequest());
     193 +// updateRequestWithResponse(identifier, arrivalTime, httpMessage);
     194 +// }
     195 +// }
     196 +// }
     197 +//
     198 +// /**
     199 +// * Since this method runs after processHttpMessage, we must use it to get the final response for proxy tool requests
     200 +// * otherwise, changes to the message by other tools using processProxyMessage would not be seen!
     201 +// *
     202 +// * @param isRequestOnly
     203 +// * @param proxyMessage
     204 +// */
     205 +// @Override
     206 +// public void processProxyMessage(final boolean isRequestOnly, final IInterceptedProxyMessage proxyMessage) {
     207 +// final int toolFlag = IBurpExtendermontoya.TOOL_PROXY;
     208 +// if (proxyMessage == null || !(Boolean) preferences.getSetting(PREF_ENABLED) || !isValidTool(toolFlag)) return;
     209 +// Date arrivalTime = new Date();
     210 +//
     211 +// if (isRequestOnly) {
     212 +//
     213 +// } else { //We only want to handle responses.
     214 +// Integer identifier = LogProcessorHelper.extractAndRemoveIdentifierFromRequestResponseComment(proxyMessage.getMessageInfo());
     215 +// updateRequestWithResponse(identifier, arrivalTime, proxyMessage.getMessageInfo());
     216 +// }
     217 +// }
     218 + 
    129 219   /**
    130 220   * When a response comes in, determine if the request has already been processed or not.
    131 221   * If it has not yet been processed, add the response information to the entry and let the original job handle it.
    skipped 2 lines
    134 224   *
    135 225   * @param entryIdentifier The unique UUID for the log entry.
    136 226   * @param arrivalTime The arrival time of the response.
    137  - * @param requestResponse The HTTP request response object.
     227 + * @param response The HTTP request response object.
    138 228   */
    139  - private void updateRequestWithResponse(Integer entryIdentifier, Date arrivalTime, IHttpRequestResponse requestResponse) {
     229 + private void updateRequestWithResponse(Integer entryIdentifier, Date arrivalTime, HttpResponse response) {
    140 230   if (entriesPendingProcessing.containsKey(entryIdentifier)) {
    141 231   //Not yet started processing the entry, we can add the response so it is processed in the first pass
    142 232   final LogEntry logEntry = entriesPendingProcessing.get(entryIdentifier);
    143  - //Update the requestResponse with the new one, and tell it when it arrived.
    144  - logEntry.addResponse(requestResponse, arrivalTime);
     233 + //Update the response with the new one, and tell it when it arrived.
     234 + logEntry.addResponse(response, arrivalTime);
    145 235   
    146 236   //Do nothing now, there's already a runnable submitted to process it somewhere in the queue.
    147 237   return;
    skipped 6 lines
    154 244   
    155 245   //Submit a job for the processing of its response.
    156 246   //This will block on the request finishing processing, then update the response and process it separately.
    157  - entryProcessExecutor.submit(createEntryUpdateRunnable(processingFuture, requestResponse, arrivalTime));
     247 + entryProcessExecutor.submit(createEntryUpdateRunnable(processingFuture, response, arrivalTime));
    158 248   } else {
    159 249   //Unknown Identifier. Potentially for a request which was ignored or cleaned up already?
    160 250   }
    skipped 39 lines
    200 290   if (logEntry.getStatus() == Status.IGNORED) return null; //Don't care about entry
    201 291   
    202 292   //Check against color filters
    203  - HashMap<UUID, ColorFilter> colorFilters = preferences.getSetting(PREF_COLOR_FILTERS);
    204  - for (ColorFilter colorFilter : colorFilters.values()) {
    205  - logEntry.testColorFilter(colorFilter, true);
     293 + HashMap<UUID, TableColorRule> colorFilters = preferences.getSetting(PREF_COLOR_FILTERS);
     294 + for (TableColorRule tableColorRule : colorFilters.values()) {
     295 + logEntry.testColorFilter(tableColorRule, true);
    206 296   }
    207 297   
    208 298   //Check against tags
    skipped 7 lines
    216 306   }
    217 307   
    218 308   private RunnableFuture<LogEntry> createEntryUpdateRunnable(final Future<LogEntry> processingFuture,
    219  - final IHttpRequestResponse requestResponse,
     309 + final HttpResponse requestResponse,
    220 310   final Date arrivalTime){
    221 311   return new FutureTask<>(() -> {
    222 312   //Block until initial processing is complete.
    skipped 24 lines
    247 337   //TODO Remove to more suitable UI class and show dialog
    248 338   
    249 339   //Build list of entries to import
    250  - IHttpRequestResponse[] proxyHistory = LoggerPlusPlus.callbacks.getProxyHistory();
     340 + List<ProxyHttpRequestResponse> proxyHistory = LoggerPlusPlus.montoya.proxy().history();
    251 341   int maxEntries = preferences.getSetting(PREF_MAXIMUM_ENTRIES);
    252  - int startIndex = Math.max(proxyHistory.length - maxEntries, 0);
    253  - List<IHttpRequestResponse> entriesToImport = Arrays.asList(proxyHistory).subList(startIndex, proxyHistory.length);
     342 + int startIndex = Math.max(proxyHistory.size() - maxEntries, 0);
     343 + List<ProxyHttpRequestResponse> entriesToImport = proxyHistory.subList(startIndex, proxyHistory.size());
    254 344   
    255 345   //Build and start import worker
    256 346   EntryImportWorker importWorker = new EntryImportWorker.Builder(this)
    257  - .setOriginatingTool(IBurpExtenderCallbacks.TOOL_PROXY)
    258  - .setEntries(entriesToImport)
     347 + .setOriginatingTool(ToolType.PROXY)
     348 + .setProxyEntries(entriesToImport)
    259 349   .setSendToAutoExporters(sendToAutoExporters).build();
    260 350   
    261 351   importWorker.execute();
    262 352   }
    263 353   
    264  - private boolean isValidTool(int toolFlag){
    265  - return ((Boolean) preferences.getSetting(PREF_LOG_GLOBAL) ||
    266  - ((Boolean) preferences.getSetting(PREF_LOG_PROXY) && toolFlag== IBurpExtenderCallbacks.TOOL_PROXY) ||
    267  - ((Boolean) preferences.getSetting(PREF_LOG_INTRUDER) && toolFlag== IBurpExtenderCallbacks.TOOL_INTRUDER) ||
    268  - ((Boolean) preferences.getSetting(PREF_LOG_REPEATER) && toolFlag== IBurpExtenderCallbacks.TOOL_REPEATER) ||
    269  - ((Boolean) preferences.getSetting(PREF_LOG_SCANNER) && toolFlag== IBurpExtenderCallbacks.TOOL_SCANNER) ||
    270  - ((Boolean) preferences.getSetting(PREF_LOG_SEQUENCER) && toolFlag== IBurpExtenderCallbacks.TOOL_SEQUENCER) ||
    271  - ((Boolean) preferences.getSetting(PREF_LOG_SPIDER) && toolFlag== IBurpExtenderCallbacks.TOOL_SPIDER) ||
    272  - ((Boolean) preferences.getSetting(PREF_LOG_EXTENDER) && toolFlag == IBurpExtenderCallbacks.TOOL_EXTENDER) ||
    273  - ((Boolean) preferences.getSetting(PREF_LOG_TARGET_TAB) && toolFlag == IBurpExtenderCallbacks.TOOL_TARGET));
     354 + private boolean isValidTool(ToolType toolType){
     355 + if(preferences.getSetting(PREF_LOG_GLOBAL)) return true;
     356 + 
     357 + switch (toolType){
     358 + case PROXY -> {return preferences.getSetting(PREF_LOG_PROXY);}
     359 + case INTRUDER -> {return preferences.getSetting(PREF_LOG_INTRUDER);}
     360 + case REPEATER -> {return preferences.getSetting(PREF_LOG_REPEATER);}
     361 + case EXTENSIONS -> {return preferences.getSetting(PREF_LOG_EXTENSIONS);}
     362 + case SCANNER -> {return preferences.getSetting(PREF_LOG_SCANNER);}
     363 + case SEQUENCER -> {return preferences.getSetting(PREF_LOG_SEQUENCER);}
     364 + case SUITE -> {return preferences.getSetting(PREF_LOG_SUITE);}
     365 + case RECORDED_LOGIN_REPLAYER -> {return preferences.getSetting(PREF_LOG_RECORDED_LOGINS);}
     366 + default -> {return false;}
     367 + }
    274 368   }
    275 369   
    276 370   public void shutdown() {
    skipped 55 lines
    332 426   long responseTimeout = 1000 * ((Integer) preferences.getSetting(PREF_RESPONSE_TIMEOUT)).longValue();
    333 427   if (timeNow - entryTime > responseTimeout) {
    334 428   iter.remove();
    335  - if (logEntry.getTool() == IBurpExtenderCallbacks.TOOL_PROXY) {
     429 + if (logEntry.getTool() == ToolType.PROXY) {
    336 430   //Remove the identifier from the comment.
    337  - LogEntry.extractAndRemoveIdentifierFromComment(logEntry);
     431 + //TODO Fix Comment cleanup
     432 +// LogEntry.extractAndRemoveIdentifierFromComment(logEntry);
    338 433   }
    339 434   logEntry.setComment(logEntry.getComment() + " Timed Out");
    340 435   }
    skipped 10 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/logview/processor/LogProcessorHelper.java
    1 1  package com.nccgroup.loggerplusplus.logview.processor;
    2 2   
    3  -import burp.IHttpRequestResponse;
     3 +import burp.api.montoya.core.Annotations;
    4 4  import com.nccgroup.loggerplusplus.util.Globals;
     5 +import org.apache.commons.lang3.StringUtils;
    5 6   
    6 7  import java.util.regex.Matcher;
    7 8   
    8 9  public class LogProcessorHelper {
    9 10   
    10  - public static void addIdentifierInComment(Integer identifier, IHttpRequestResponse requestResponse) {
    11  - String originalComment = requestResponse.getComment() != null ? requestResponse.getComment() : "";
    12  - requestResponse.setComment(originalComment + "$LPP:" + identifier + "$");
     11 + public static Annotations addIdentifierInComment(Integer identifier, Annotations annotations) {
     12 + String originalComment = annotations.notes() != null ? annotations.notes() : "";
     13 + annotations = annotations.withNotes(originalComment + "$LPP:" + identifier + "$");
     14 + return annotations;
    13 15   }
    14 16   
    15  - public static Integer extractAndRemoveIdentifierFromRequestResponseComment(IHttpRequestResponse requestResponse) {
     17 + public static Object[] extractAndRemoveIdentifierFromRequestResponseComment(Annotations annotations) {
    16 18   Integer identifier = null;
    17  - if (requestResponse.getComment() != null) {
    18  - Matcher matcher = Globals.LOG_ENTRY_ID_PATTERN.matcher(requestResponse.getComment());
     19 + if (!StringUtils.isEmpty(annotations.notes())) {
     20 + Matcher matcher = Globals.LOG_ENTRY_ID_PATTERN.matcher(annotations.notes());
    19 21   if (matcher.find()) {
    20 22   identifier = Integer.parseInt(matcher.group(1));
    21  - requestResponse.setComment(matcher.replaceAll(""));
     23 + annotations = annotations.withNotes(matcher.replaceAll(""));
    22 24   }
    23 25   }
    24 26   
    25  - return identifier;
     27 + return new Object[]{identifier,annotations};
    26 28   }
    27 29  }
    28 30   
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/preferences/LoggerPreferenceFactory.java
    1 1  package com.nccgroup.loggerplusplus.preferences;
    2 2   
    3  -import burp.IBurpExtenderCallbacks;
     3 +import burp.api.montoya.MontoyaApi;
    4 4  import com.coreyd97.BurpExtenderUtilities.IGsonProvider;
    5 5  import com.coreyd97.BurpExtenderUtilities.ILogProvider;
    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.filter.colorfilter.ColorFilter;
    10  -import com.nccgroup.loggerplusplus.filter.logfilter.LogFilter;
     9 +import com.nccgroup.loggerplusplus.filter.*;
     10 +import com.nccgroup.loggerplusplus.filter.colorfilter.TableColorRule;
     11 +import com.nccgroup.loggerplusplus.filter.logfilter.LogTableFilter;
    11 12  import com.nccgroup.loggerplusplus.filter.savedfilter.SavedFilter;
    12 13  import com.nccgroup.loggerplusplus.filter.tag.Tag;
    13 14  import com.nccgroup.loggerplusplus.logentry.LogEntry;
    skipped 2 lines
    16 17  import com.nccgroup.loggerplusplus.logentry.LogEntrySerializer;
    17 18  import com.nccgroup.loggerplusplus.logview.logtable.LogTableColumn;
    18 19  import com.nccgroup.loggerplusplus.util.Globals;
     20 +import lombok.extern.log4j.Log4j2;
    19 21  import org.apache.logging.log4j.Level;
    20 22   
    21 23  import javax.swing.*;
    skipped 1 lines
    23 25   
    24 26  import static com.nccgroup.loggerplusplus.util.Globals.*;
    25 27   
     28 +@Log4j2
    26 29  public class LoggerPreferenceFactory extends PreferenceFactory {
    27 30   
    28  - private HashMap<UUID, ColorFilter> defaultColorFilters;
     31 + private HashMap<UUID, TableColorRule> defaultColorFilters;
    29 32   private ArrayList<LogTableColumn> defaultlogTableColumns;
    30 33   private Set<String> defaultBlacklistedReflections;
    31 34   
    32  - public LoggerPreferenceFactory(IGsonProvider gsonProvider, ILogProvider logProvider, IBurpExtenderCallbacks callbacks){
    33  - super("LoggerPlusPlus", gsonProvider, logProvider, callbacks);
     35 + public LoggerPreferenceFactory(MontoyaApi montoya, IGsonProvider gsonProvider, ILogProvider logProvider){
     36 + super(montoya, "LoggerPlusPlus", gsonProvider, logProvider);
    34 37   }
    35 38   
    36  - public LoggerPreferenceFactory(IGsonProvider gsonProvider, IBurpExtenderCallbacks callbacks){
    37  - super("LoggerPlusPlus", gsonProvider, callbacks);
     39 + public LoggerPreferenceFactory(MontoyaApi montoya, IGsonProvider gsonProvider){
     40 + super(montoya, "LoggerPlusPlus", gsonProvider);
    38 41   }
    39 42   
    40 43   @Override
    41 44   protected void createDefaults(){
     45 + 
     46 + 
    42 47   defaultColorFilters = this.gsonProvider.getGson().fromJson(
    43  - Globals.DEFAULT_COLOR_FILTERS_JSON, new TypeToken<HashMap<UUID, ColorFilter>>(){}.getType());
     48 + Globals.DEFAULT_COLOR_FILTERS_JSON, new TypeToken<HashMap<UUID, TableColorRule>>(){}.getType());
     49 + log.info(DEFAULT_LOG_TABLE_COLUMNS_JSON);
    44 50   defaultlogTableColumns = this.gsonProvider.getGson().fromJson(
    45 51   Globals.DEFAULT_LOG_TABLE_COLUMNS_JSON, new TypeToken<List<LogTableColumn>>() {}.getType());
    46 52   defaultBlacklistedReflections = new TreeSet(String.CASE_INSENSITIVE_ORDER);
    skipped 3 lines
    50 56   @Override
    51 57   protected void registerTypeAdapters(){
    52 58   this.gsonProvider.registerTypeAdapter(LogEntryField.class, new LogEntryFieldSerializer());
    53  - this.gsonProvider.registerTypeAdapter(LogFilter.class, new LogFilter.FilterSerializer());
     59 + this.gsonProvider.registerTypeAdapter(FilterExpression.class, new FilterExpressionSerializer());
     60 + this.gsonProvider.registerTypeAdapter(Tag.class, new TagSerializer());
     61 + this.gsonProvider.registerTypeAdapter(TableColorRule.class, new TableColorRuleSerializer());
     62 + this.gsonProvider.registerTypeAdapter(SavedFilter.class, new SavedFilterSerializer());
    54 63   this.gsonProvider.registerTypeAdapter(LogTableColumn.class, new LogTableColumn.ColumnSerializer());
    55 64   this.gsonProvider.registerTypeAdapter(LogEntry.class, new LogEntrySerializer());
    56 65   }
    skipped 14 lines
    71 80   prefs.registerSetting(PREF_LOG_SCANNER, Boolean.class, true);
    72 81   prefs.registerSetting(PREF_LOG_REPEATER, Boolean.class, true);
    73 82   prefs.registerSetting(PREF_LOG_SEQUENCER, Boolean.class, true);
    74  - prefs.registerSetting(PREF_LOG_EXTENDER, Boolean.class, true);
     83 + prefs.registerSetting(PREF_LOG_EXTENSIONS, Boolean.class, true);
    75 84   prefs.registerSetting(PREF_LOG_TARGET_TAB, Boolean.class, true);
    76 85   prefs.registerSetting(PREF_MAX_RESP_SIZE, Integer.class, 10); //Default 10MB
    77  - prefs.registerSetting(PREF_COLOR_FILTERS, new TypeToken<Map<UUID, ColorFilter>>() {
     86 + prefs.registerSetting(PREF_TABLE_PILL_STYLE, Boolean.class, true);
     87 + prefs.registerSetting(PREF_COLOR_FILTERS, new TypeToken<Map<UUID, TableColorRule>>() {
    78 88   }.getType(), defaultColorFilters);
    79 89   prefs.registerSetting(PREF_TAG_FILTERS, new TypeToken<Map<UUID, Tag>>() {
    80 90   }.getType(), new HashMap<>());
    skipped 44 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/preferences/PreferencesController.java
    1 1  package com.nccgroup.loggerplusplus.preferences;
    2 2   
     3 +import burp.api.montoya.MontoyaApi;
    3 4  import com.coreyd97.BurpExtenderUtilities.IGsonProvider;
    4 5  import com.coreyd97.BurpExtenderUtilities.ILogProvider;
    5 6  import com.coreyd97.BurpExtenderUtilities.Preferences;
    6 7  import com.nccgroup.loggerplusplus.LoggerPlusPlus;
     8 +import lombok.Getter;
     9 +import lombok.extern.log4j.Log4j2;
    7 10  import org.apache.logging.log4j.LogManager;
    8 11  import org.apache.logging.log4j.Logger;
    9 12   
     13 +@Log4j2
    10 14  public class PreferencesController {
    11  - private final LoggerPlusPlus loggerPlusPlus;
     15 + 
     16 + @Getter
    12 17   private final IGsonProvider gsonProvider;
     18 + 
     19 + @Getter
    13 20   private final Preferences preferences;
    14 21   
    15 22   private PreferencesPanel preferencesPanel;
    16 23   
    17  - private Logger logger = LogManager.getLogger(this.getClass());
    18  - 
    19  - public PreferencesController(LoggerPlusPlus loggerPlusPlus) {
    20  - this.loggerPlusPlus = loggerPlusPlus;
    21  - this.gsonProvider = loggerPlusPlus.getGsonProvider();
    22  - this.preferences = new LoggerPreferenceFactory(
     24 + public PreferencesController(MontoyaApi montoya) {
     25 + this.gsonProvider = LoggerPlusPlus.gsonProvider;
     26 + this.preferences = new LoggerPreferenceFactory(montoya,
    23 27   gsonProvider,
    24 28   new ILogProvider() {
    25 29   @Override
    26 30   public void logOutput(String message) {
    27  - logger.debug(message);
     31 + log.debug(message);
    28 32   }
    29 33   
    30 34   @Override
    31 35   public void logError(String errorMessage) {
    32  - logger.error(errorMessage);
     36 + log.error(errorMessage);
    33 37   }
    34  - },
    35  - LoggerPlusPlus.callbacks
     38 + }
    36 39   ).buildPreferences();
    37 40   }
    38 41   
    39 42   public PreferencesPanel getPreferencesPanel() {
    40  - if(preferencesPanel == null) {
    41  - preferencesPanel = new PreferencesPanel(this);
     43 + if(this.preferencesPanel == null) {
     44 + this.preferencesPanel = new PreferencesPanel(this);
    42 45   }
     46 + 
    43 47   return preferencesPanel;
    44  - }
    45  - 
    46  - public LoggerPlusPlus getLoggerPlusPlus() {
    47  - return loggerPlusPlus;
    48  - }
    49  - 
    50  - public IGsonProvider getGsonProvider() {
    51  - return gsonProvider;
    52  - }
    53  - 
    54  - public Preferences getPreferences() {
    55  - return preferences;
    56 48   }
    57 49  }
    58 50   
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/preferences/PreferencesPanel.java
    skipped 11 lines
    12 12   
    13 13  package com.nccgroup.loggerplusplus.preferences;
    14 14   
    15  -import burp.IHttpRequestResponse;
     15 +import burp.api.montoya.http.message.HttpRequestResponse;
    16 16  import com.coreyd97.BurpExtenderUtilities.Alignment;
    17 17  import com.coreyd97.BurpExtenderUtilities.ComponentGroup;
    18 18  import com.coreyd97.BurpExtenderUtilities.ComponentGroup.Orientation;
    skipped 2 lines
    21 21  import com.google.gson.reflect.TypeToken;
    22 22  import com.nccgroup.loggerplusplus.LoggerPlusPlus;
    23 23  import com.nccgroup.loggerplusplus.exports.*;
    24  -import com.nccgroup.loggerplusplus.filter.colorfilter.ColorFilter;
     24 +import com.nccgroup.loggerplusplus.filter.colorfilter.TableColorRule;
    25 25  import com.nccgroup.loggerplusplus.filter.savedfilter.SavedFilter;
    26 26  import com.nccgroup.loggerplusplus.imports.LoggerImport;
     27 +import com.nccgroup.loggerplusplus.logentry.LogEntryField;
     28 +import com.nccgroup.loggerplusplus.logview.logtable.LogTableColumn;
     29 +import com.nccgroup.loggerplusplus.logview.logtable.LogTableColumnModel;
    27 30  import com.nccgroup.loggerplusplus.util.MoreHelp;
     31 +import com.nccgroup.loggerplusplus.util.userinterface.renderer.TagRenderer;
    28 32   
    29 33  import javax.swing.*;
     34 +import javax.swing.table.DefaultTableCellRenderer;
    30 35  import java.awt.*;
    31 36  import java.awt.event.ActionEvent;
    32  -import java.util.ArrayList;
    33  -import java.util.HashMap;
    34  -import java.util.Map;
    35  -import java.util.UUID;
     37 +import java.util.*;
    36 38   
    37 39  import static com.nccgroup.loggerplusplus.util.Globals.*;
    38 40   
    skipped 38 lines
    77 79   JCheckBox logSequencer = logFromPanel.addPreferenceComponent(preferences, PREF_LOG_SEQUENCER, "Sequencer");
    78 80   JCheckBox logProxy = logFromPanel.addPreferenceComponent(preferences, PREF_LOG_PROXY, "Proxy");
    79 81   JCheckBox logTarget = logFromPanel.addPreferenceComponent(preferences, PREF_LOG_TARGET_TAB, "Target");
    80  - JCheckBox logExtender = logFromPanel.addPreferenceComponent(preferences, PREF_LOG_EXTENDER, "Extender");
     82 + JCheckBox logExtender = logFromPanel.addPreferenceComponent(preferences, PREF_LOG_EXTENSIONS, "Extender");
    81 83   
    82 84   strutConstraints = logFromPanel.generateNextConstraints(true);
    83 85   strutConstraints.weighty = strutConstraints.weightx = 0;
    skipped 31 lines
    115 117   importGroup.add(new JButton(new AbstractAction("Import Burp Proxy History") {
    116 118   @Override
    117 119   public void actionPerformed(ActionEvent e) {
    118  - int historySize = LoggerPlusPlus.callbacks.getProxyHistory().length;
     120 + int historySize = LoggerPlusPlus.montoya.proxy().history().size();
    119 121   int maxEntries = preferences.getSetting(PREF_MAXIMUM_ENTRIES);
    120 122   String message = "Import " + historySize
    121 123   + " items from burp suite proxy history? This will clear the current entries."
    skipped 15 lines
    137 139   sendToAutoExporters = res == JOptionPane.YES_OPTION;
    138 140   }
    139 141   
    140  - preferencesController.getLoggerPlusPlus().getLogProcessor().importProxyHistory(sendToAutoExporters);
     142 + LoggerPlusPlus.instance.getLogProcessor().importProxyHistory(sendToAutoExporters);
    141 143   }
    142 144   }
    143 145   }));
    skipped 1 lines
    145 147   importGroup.add(new JButton(new AbstractAction("Import From WStalker CSV") {
    146 148   @Override
    147 149   public void actionPerformed(ActionEvent e) {
    148  - ArrayList<IHttpRequestResponse> requests = LoggerImport.importWStalker();
     150 + ArrayList<HttpRequestResponse> requests = LoggerImport.importWStalker();
    149 151   if (LoggerPlusPlus.instance.getExportController().getEnabledExporters().size() > 0) {
    150 152   int res = JOptionPane.showConfirmDialog(LoggerPlusPlus.instance.getLoggerFrame(),
    151 153   "One or more auto-exporters are currently enabled. " +
    skipped 9 lines
    161 163   importGroup.add(new JButton(new AbstractAction("Import From OWASP ZAP") {
    162 164   @Override
    163 165   public void actionPerformed(ActionEvent e) {
    164  - ArrayList<IHttpRequestResponse> requests = LoggerImport.importZAP();
     166 + ArrayList<HttpRequestResponse> requests = LoggerImport.importZAP();
    165 167   
    166 168   if (LoggerPlusPlus.instance.getExportController().getEnabledExporters().size() > 0) {
    167 169   int res = JOptionPane.showConfirmDialog(LoggerPlusPlus.instance.getLoggerFrame(),
    skipped 8 lines
    176 178   }));
    177 179   
    178 180   ComponentGroup exportGroup = new ComponentGroup(Orientation.HORIZONTAL);
    179  - HashMap<Class<? extends LogExporter>, LogExporter> exporters = preferencesController.getLoggerPlusPlus()
     181 + HashMap<Class<? extends LogExporter>, LogExporter> exporters = LoggerPlusPlus.instance
    180 182   .getExportController().getExporters();
    181 183   exportGroup.add(((ExportPanelProvider) exporters.get(CSVExporter.class)).getExportPanel());
    182 184   exportGroup.add(((ExportPanelProvider) exporters.get(JSONExporter.class)).getExportPanel());
    skipped 25 lines
    208 210   ((SpinnerNumberModel) maxResponseSize.getModel()).setMaximum(1000000);
    209 211   ((SpinnerNumberModel) maxResponseSize.getModel()).setStepSize(1);
    210 212   
     213 + JCheckBox tagStyle = otherPanel.addPreferenceComponent(preferences, PREF_TABLE_PILL_STYLE, "Display matching tags as pill components");
     214 + 
     215 + preferences.addSettingListener((source, settingName, newValue) -> {
     216 + if(Objects.equals(settingName, PREF_TABLE_PILL_STYLE)){
     217 + LogTableColumnModel columnModel = LoggerPlusPlus.instance.getLogViewController().getLogViewPanel().getLogTable().getColumnModel();
     218 + Optional<LogTableColumn> column = columnModel.getAllColumns().stream().filter(logTableColumn -> logTableColumn.getIdentifier() == LogEntryField.TAGS).findFirst();
     219 + if(column.isEmpty()) return;
     220 + if((boolean) newValue) {
     221 + column.get().setCellRenderer(new TagRenderer());
     222 + }else{
     223 + column.get().setCellRenderer(new DefaultTableCellRenderer());
     224 + }
     225 + }
     226 + });
     227 + 
    211 228   ComponentGroup savedFilterSharing = new ComponentGroup(Orientation.VERTICAL, "Saved Filter Sharing");
    212 229   savedFilterSharing.add(new JButton(new AbstractAction("Import Saved Filters") {
    213 230   @Override
    skipped 25 lines
    239 256   @Override
    240 257   public void actionPerformed(ActionEvent e) {
    241 258   String json = MoreHelp.showLargeInputDialog("Import Color Filters", null);
    242  - Map<UUID, ColorFilter> colorFilterMap = preferencesController.getGsonProvider().getGson().fromJson(json,
    243  - new TypeToken<Map<UUID, ColorFilter>>() {
     259 + Map<UUID, TableColorRule> colorFilterMap = preferencesController.getGsonProvider().getGson().fromJson(json,
     260 + new TypeToken<Map<UUID, TableColorRule>>() {
    244 261   }.getType());
    245  - for (ColorFilter colorFilter : colorFilterMap.values()) {
    246  - LoggerPlusPlus.instance.getLibraryController().addColorFilter(colorFilter);
     262 + for (TableColorRule tableColorRule : colorFilterMap.values()) {
     263 + LoggerPlusPlus.instance.getLibraryController().addColorFilter(tableColorRule);
    247 264   }
    248 265   }
    249 266   }));
    skipped 1 lines
    251 268   colorFilterSharing.add(new JButton(new AbstractAction("Export Color Filters") {
    252 269   @Override
    253 270   public void actionPerformed(ActionEvent e) {
    254  - HashMap<UUID, ColorFilter> colorFilters = preferences.getSetting(PREF_COLOR_FILTERS);
     271 + HashMap<UUID, TableColorRule> colorFilters = preferences.getSetting(PREF_COLOR_FILTERS);
    255 272   String jsonOutput = preferencesController.getGsonProvider().getGson().toJson(colorFilters);
    256 273   MoreHelp.showLargeOutputDialog("Export Color Filters", jsonOutput);
    257 274   }
    skipped 22 lines
    280 297   JOptionPane.YES_NO_OPTION);
    281 298   if (result == JOptionPane.YES_OPTION) {
    282 299   preferences.resetSettings(preferences.getRegisteredSettings().keySet());
    283  - preferencesController.getLoggerPlusPlus().getLogViewController().getLogTableController()
     300 + LoggerPlusPlus.instance.getLogViewController().getLogTableController()
    284 301   .reinitialize();
    285 302   }
    286 303   }
    skipped 2 lines
    289 306   resetPanel.add(new JButton(new AbstractAction("Clear The Logs") {
    290 307   @Override
    291 308   public void actionPerformed(ActionEvent e) {
    292  - preferencesController.getLoggerPlusPlus().getLogViewController().getLogTableController().reset();
     309 + LoggerPlusPlus.instance.getLogViewController().getLogTableController().reset();
    293 310   }
    294 311   }));
    295 312   
    skipped 29 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/reflection/ReflectionController.java
    1 1  package com.nccgroup.loggerplusplus.reflection;
    2 2   
    3  -import burp.IParameter;
     3 +import burp.api.montoya.http.message.params.HttpParameter;
    4 4  import com.coreyd97.BurpExtenderUtilities.Alignment;
    5 5  import com.coreyd97.BurpExtenderUtilities.PanelBuilder;
    6 6  import com.coreyd97.BurpExtenderUtilities.Preferences;
    skipped 2 lines
    9 9  import com.nccgroup.loggerplusplus.reflection.filter.LengthFilter;
    10 10  import com.nccgroup.loggerplusplus.reflection.filter.ParameterFilter;
    11 11  import com.nccgroup.loggerplusplus.reflection.transformer.*;
    12  -import com.nccgroup.loggerplusplus.util.MoreHelp;
    13 12  import com.nccgroup.loggerplusplus.util.userinterface.renderer.BooleanRenderer;
    14 13  import com.nccgroup.loggerplusplus.util.userinterface.renderer.ButtonRenderer;
    15 14   
    16 15  import javax.swing.*;
    17  -import javax.swing.table.AbstractTableModel;
    18 16  import javax.swing.table.DefaultTableModel;
    19 17  import java.awt.*;
    20  -import java.awt.event.ActionEvent;
    21 18  import java.awt.event.MouseAdapter;
    22 19  import java.awt.event.MouseEvent;
    23  -import java.util.*;
     20 +import java.util.ArrayList;
    24 21  import java.util.List;
    25  -import java.util.regex.Matcher;
    26 22  import java.util.regex.Pattern;
    27 23   
    28 24  public class ReflectionController {
    skipped 18 lines
    47 43   transformerList.add(new XMLUnescapeTransformer(preferences));
    48 44   }
    49 45   
    50  - public List<IParameter> filterParameters(List<IParameter> allParameters){
    51  - List<IParameter> interestingParameters = new ArrayList<>();
    52  - for (IParameter parameter : allParameters) {
     46 + public List<HttpParameter> filterParameters(List<? extends HttpParameter> allParameters){
     47 + List<HttpParameter> interestingParameters = new ArrayList<>();
     48 + for (HttpParameter parameter : allParameters) {
    53 49   if(!isParameterFiltered(parameter)) interestingParameters.add(parameter);
    54 50   }
    55 51   return interestingParameters;
    56 52   }
    57 53  
    58  - public boolean isParameterFiltered(IParameter parameter){
     54 + public boolean isParameterFiltered(HttpParameter parameter){
    59 55   for (ParameterFilter filter : filterList) {
    60 56   if(!filter.isEnabled()) continue;
    61 57   if(filter.isFiltered(parameter)){
    skipped 3 lines
    65 61   return false;
    66 62   }
    67 63  
    68  - public boolean validReflection(String responseBody, IParameter param){
    69  - if(param.getName().isEmpty() || param.getValue().isEmpty()) return false;
     64 + public boolean validReflection(String responseBody, HttpParameter param){
     65 + if(param.name().isEmpty() || param.value().isEmpty()) return false;
    70 66   
    71  - if(responseBody.contains(param.getValue())) return true;
     67 + if(responseBody.contains(param.value())) return true;
    72 68   
    73 69   for (ParameterValueTransformer transformer : transformerList) {
    74 70   try {
    75 71   if (transformer.isEnabled()){
    76  - Pattern pattern = Pattern.compile("\\Q"+transformer.transform(param.getValue())+"\\E", Pattern.CASE_INSENSITIVE);
     72 + Pattern pattern = Pattern.compile("\\Q"+transformer.transform(param.value())+"\\E", Pattern.CASE_INSENSITIVE);
    77 73   if(pattern.matcher(responseBody).find()){
    78 74   return true;
    79 75   }
    skipped 167 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/reflection/filter/BlacklistFilter.java
    1 1  package com.nccgroup.loggerplusplus.reflection.filter;
    2 2   
    3  -import burp.IParameter;
    4  -import com.coreyd97.BurpExtenderUtilities.PanelBuilder;
     3 +import burp.api.montoya.http.message.params.HttpParameter;
    5 4  import com.coreyd97.BurpExtenderUtilities.Preferences;
    6 5  import com.google.gson.reflect.TypeToken;
    7 6  import com.nccgroup.loggerplusplus.util.MoreHelp;
    8 7  import org.apache.commons.lang3.StringUtils;
    9 8   
    10  -import javax.swing.*;
    11 9  import java.util.Arrays;
    12 10  import java.util.HashSet;
    13 11  import java.util.Set;
    skipped 14 lines
    28 26   }
    29 27   
    30 28   @Override
    31  - public boolean isFiltered(IParameter parameter) {
    32  - return blacklist.contains(parameter.getValue());
     29 + public boolean isFiltered(HttpParameter parameter) {
     30 + return blacklist.contains(parameter.value());
    33 31   }
    34 32   
    35 33   @Override
    skipped 13 lines
  • ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/reflection/filter/LengthFilter.java
    1 1  package com.nccgroup.loggerplusplus.reflection.filter;
    2 2   
    3  -import burp.IParameter;
     3 +import burp.api.montoya.http.message.params.HttpParameter;
    4 4  import com.coreyd97.BurpExtenderUtilities.Alignment;
    5 5  import com.coreyd97.BurpExtenderUtilities.PanelBuilder;
    6 6  import com.coreyd97.BurpExtenderUtilities.Preferences;
    7  -import com.google.gson.reflect.TypeToken;
    8 7  import com.nccgroup.loggerplusplus.LoggerPlusPlus;
    9  -import com.nccgroup.loggerplusplus.util.MoreHelp;
    10  -import org.apache.commons.lang3.StringUtils;
    11 8   
    12 9  import javax.swing.*;
    13  -import java.util.Arrays;
    14  -import java.util.HashSet;
    15  -import java.util.Set;
    16  -import java.util.TreeSet;
    17  -import java.util.logging.Logger;
    18 10   
    19 11  public class LengthFilter extends ParameterFilter {
    20 12   
    skipped 12 lines
    33 25   }
    34 26   
    35 27   @Override
    36  - public boolean isFiltered(IParameter parameter) {
    37  - int len = parameter.getValue().length();
     28 + public boolean isFiltered(HttpParameter parameter) {
     29 + int len = parameter.value().length();
    38 30   return len < min_length || len > max_length;
    39 31   
    40 32   }
    skipped 25 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/reflection/filter/ParameterFilter.java
    1 1  package com.nccgroup.loggerplusplus.reflection.filter;
    2 2   
    3  -import burp.IParameter;
     3 +import burp.api.montoya.http.message.params.HttpParameter;
    4 4  import com.coreyd97.BurpExtenderUtilities.Preferences;
    5 5   
    6 6  public abstract class ParameterFilter {
    skipped 24 lines
    31 31   return enabled;
    32 32   }
    33 33   
    34  - public abstract boolean isFiltered(IParameter parameter);
     34 + public abstract boolean isFiltered(HttpParameter parameter);
    35 35   public abstract void showConfigDialog();
    36 36   
    37 37  }
    skipped 1 lines
  • ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/reflection/transformer/Base64EncodeTransformer.java
    skipped 2 lines
    3 3  import com.coreyd97.BurpExtenderUtilities.Preferences;
    4 4   
    5 5  import java.io.UnsupportedEncodingException;
    6  -import java.net.URLEncoder;
    7 6  import java.util.Base64;
    8 7   
    9 8  public class Base64EncodeTransformer extends ParameterValueTransformer {
    skipped 11 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/reflection/transformer/HTMLEscapeTransformer.java
    1 1  package com.nccgroup.loggerplusplus.reflection.transformer;
    2 2   
    3 3  import com.coreyd97.BurpExtenderUtilities.Preferences;
    4  -import org.apache.commons.lang3.StringUtils;
    5 4  import org.apache.commons.text.StringEscapeUtils;
    6  - 
    7  -import java.io.UnsupportedEncodingException;
    8  -import java.net.URLEncoder;
    9 5   
    10 6  public class HTMLEscapeTransformer extends ParameterValueTransformer {
    11 7   
    skipped 10 lines
  • ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/reflection/transformer/HexEncodeTransformer.java
    skipped 3 lines
    4 4  import org.apache.commons.codec.binary.Hex;
    5 5   
    6 6  import java.io.UnsupportedEncodingException;
    7  -import java.util.Base64;
    8 7   
    9 8  public class HexEncodeTransformer extends ParameterValueTransformer {
    10 9   
    skipped 10 lines
  • ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/reflection/transformer/URLDecodeTransformer.java
    skipped 3 lines
    4 4   
    5 5  import java.io.UnsupportedEncodingException;
    6 6  import java.net.URLDecoder;
    7  -import java.net.URLEncoder;
    8 7   
    9 8  public class URLDecodeTransformer extends ParameterValueTransformer {
    10 9   
    skipped 10 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/util/Globals.java
    skipped 34 lines
    35 35   public static final String PREF_LOG_SCANNER = "logscanner";
    36 36   public static final String PREF_LOG_REPEATER = "logrepeater";
    37 37   public static final String PREF_LOG_SEQUENCER = "logsequencer";
    38  - public static final String PREF_LOG_EXTENDER = "logextender";
     38 + public static final String PREF_LOG_EXTENSIONS = "logextender";
    39 39   public static final String PREF_LOG_TARGET_TAB = "logtargettab";
     40 + public static final String PREF_LOG_RECORDED_LOGINS = "logrecordedlogins";
     41 + public static final String PREF_LOG_SUITE = "logsuite";
    40 42   public static final String PREF_COLOR_FILTERS = "colorfilters";
    41 43   public static final String PREF_TAG_FILTERS = "tagfilters";
    42 44   public static final String PREF_SAVED_FILTERS = "savedfilters";
    skipped 30 lines
    73 75   public static final String PREF_SAVED_FIELD_SELECTIONS = "savedFieldSelections";
    74 76   public static final String PREF_COLUMNS_VERSION = "columnsVersion";
    75 77   public static final String PREF_MAX_RESP_SIZE = "maxRespBodySize";
     78 + public static final String PREF_TABLE_PILL_STYLE = "tagsStyle";
    76 79   
    77 80   public enum ElasticAuthType {ApiKey, Basic, None}
    78 81   
    skipped 2 lines
    81 84   "\"filter\":{\"filter\":\"Request.Complete == False\"},\"filterString\":\"Request.Complete == False\",\"backgroundColor\":{\"value\":-16777216,\"falpha\":0.0}," +
    82 85   "\"foregroundColor\":{\"value\":-65536,\"falpha\":0.0},\"enabled\":true,\"modified\":false,\"shouldRetest\":true,\"priority\":1}}";
    83 86   
    84  - public static final int CURRENT_COLUMN_VERSION = 8;
     87 + public static final int CURRENT_COLUMN_VERSION = 9;
    85 88   private static int colOrder = 0;
    86 89   public static final String DEFAULT_LOG_TABLE_COLUMNS_JSON = new StringBuilder().append("[")
    87  - .append("{'id':" + NUMBER + ",'name':'Number','defaultVisibleName':'#','visibleName':'#','preferredWidth':65,'readonly':true,'order':" + colOrder++ + ",'visible':true,'description':'" + StringEscapeUtils.escapeJson(NUMBER.getDescription()) + "'},")
    88  - .append("{'id':" + TAGS + ",'name':'Tags','defaultVisibleName':'Tags','visibleName':'Tags','preferredWidth':100,'readonly':true,'order':" + colOrder++ + ",'visible':true,'description':'" + StringEscapeUtils.escapeJson(TAGS.getDescription()) + "'},")
    89  - .append("{'id':" + COMPLETE + ",'name':'Complete','defaultVisibleName':'Complete','visibleName':'Complete','preferredWidth':80,'readonly':true,'order':" + colOrder++ + ",'visible':true,'description':'" + StringEscapeUtils.escapeJson(COMPLETE.getDescription()) + "'},")
    90  - .append("{'id':" + PROXY_TOOL + ",'name':'Tool','defaultVisibleName':'Tool','visibleName':'Tool','preferredWidth':70,'readonly':true,'order':" + colOrder++ + ",'visible':true,'description':'" + StringEscapeUtils.escapeJson(PROXY_TOOL.getDescription()) + "'},")
    91  - .append("{'id':" + ISSSL + ",'name':'IsSSL','defaultVisibleName':'SSL','visibleName':'SSL','preferredWidth':50,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(ISSSL.getDescription()) + "'},")
    92  - .append("{'id':" + METHOD + ",'name':'Method','defaultVisibleName':'Method','visibleName':'Method','preferredWidth':65,'readonly':true,'order':" + colOrder++ + ",'visible':true,'description':'" + StringEscapeUtils.escapeJson(METHOD.getDescription()) + "'},")
    93  - .append("{'id':" + PROTOCOL + ",'name':'Protocol','defaultVisibleName':'Protocol','visibleName':'Protocol','preferredWidth':80,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(PROTOCOL.getDescription()) + "'},")
    94  - .append("{'id':" + HOSTNAME + ",'name':'Hostname','defaultVisibleName':'Host Name','visibleName':'Host Name','preferredWidth':150,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(HOSTNAME.getDescription()) + "'},")
    95  - .append("{'id':" + PORT + ",'name':'TargetPort','defaultVisibleName':'Port','visibleName':'Port','preferredWidth':50,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(PORT.getDescription()) + "'},")
    96  - .append("{'id':" + HOST + ",'name':'Host','defaultVisibleName':'Host','visibleName':'Host','preferredWidth':150,'readonly':true,'order':" + colOrder++ + ",'visible':true,'description':'" + StringEscapeUtils.escapeJson(HOST.getDescription()) + "'},")
    97  - .append("{'id':" + PATH + ",'name':'Path','defaultVisibleName':'Path','visibleName':'Path','preferredWidth':250,'readonly':true,'order':" + colOrder++ + ",'visible':true,'description':'" + StringEscapeUtils.escapeJson(PATH.getDescription()) + "'},")
    98  - .append("{'id':" + EXTENSION + ",'name':'UrlExtension','defaultVisibleName':'Extension','visibleName':'Extension','preferredWidth':70,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(EXTENSION.getDescription()) + "'},")
    99  - .append("{'id':" + QUERY + ",'name':'Query','defaultVisibleName':'Query','visibleName':'Query','preferredWidth':250,'readonly':true,'order':" + colOrder++ + ",'visible':true,'description':'" + StringEscapeUtils.escapeJson(QUERY.getDescription()) + "'},")
    100  - .append("{'id':" + PATHQUERY + ",'name':'Path Query','defaultVisibleName':'Path Query','visibleName':'Path Query','preferredWidth':250,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(PATHQUERY.getDescription()) + "'},")
    101  - .append("{'id':" + URL + ",'name':'Url','defaultVisibleName':'URL','visibleName':'URL','preferredWidth':250,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(URL.getDescription()) + "'},")
    102  - .append("{'id':" + HASPARAMS + ",'name':'Has Params','defaultVisibleName':'Has Params','visibleName':'Has Params','preferredWidth':75,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(HASPARAMS.getDescription()) + "'},")
    103  - .append("{'id':" + STATUS + ",'name':'Status','defaultVisibleName':'Status','visibleName':'Status','preferredWidth':55,'readonly':true,'order':" + colOrder++ + ",'visible':true,'description':'" + StringEscapeUtils.escapeJson(STATUS.getDescription()) + "'},")
    104  - .append("{'id':" + TITLE + ",'name':'Title','defaultVisibleName':'Title','visibleName':'Title','preferredWidth':100,'readonly':true,'order':" + colOrder++ + ",'visible':true,'description':'" + StringEscapeUtils.escapeJson(TITLE.getDescription()) + "'},")
    105  - .append("{'id':" + REQUEST_LENGTH + ",'name':'RequestLength','defaultVisibleName':'Request Length','visibleName':'Request Length','preferredWidth':150,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(REQUEST_LENGTH.getDescription()) + "'},")
    106  - .append("{'id':" + RESPONSE_LENGTH + ",'name':'ResponseLength','defaultVisibleName':'Response Length','visibleName':'Response Length','preferredWidth':125,'readonly':true,'order':" + colOrder++ + ",'visible':true,'description':'" + StringEscapeUtils.escapeJson(RESPONSE_LENGTH.getDescription()) + "'},")
    107  - .append("{'id':" + INFERRED_TYPE + ",'name':'InferredType','defaultVisibleName':'Inferred Type','visibleName':'Inferred Type','preferredWidth':100,'readonly':true,'order':" + colOrder++ + ",'visible':true,'description':'" + StringEscapeUtils.escapeJson(INFERRED_TYPE.getDescription()) + "'},")
    108  - .append("{'id':" + COMMENT + ",'name':'Comment','defaultVisibleName':'Comment','visibleName':'Comment','preferredWidth':200,'readonly':false,'order':" + colOrder++ + ",'visible':true,'description':'" + StringEscapeUtils.escapeJson(COMMENT.getDescription()) + "'},")
    109  - .append("{'id':" + PARAMETER_COUNT + ",'name':'ParameterCount','defaultVisibleName':'Parameter Count','visibleName':'Parameter Count','preferredWidth':150,'readonly':true,'order':" + colOrder++ + ",'visible':true,'description':'" + StringEscapeUtils.escapeJson(PARAMETER_COUNT.getDescription()) + "'},")
    110  - .append("{'id':" + PARAMETERS + ",'name':'Parameters','defaultVisibleName':'Parameters','visibleName':'Parameters','preferredWidth':150,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(PARAMETERS.getDescription()) + "'},")
    111  - .append("{'id':" + REFLECTED_PARAMS + ",'name':'ReflectedParams','defaultVisibleName':'Reflected Params','visibleName':'Reflected Params','preferredWidth':150,'readonly':true,'order':" + colOrder++ + ",'visible':true,'description':'" + StringEscapeUtils.escapeJson(REFLECTED_PARAMS.getDescription()) + "'},")
    112  - .append("{'id':" + REFLECTION_COUNT + ",'name':'ReflectionCount','defaultVisibleName':'Reflection Count','visibleName':'Reflection Count','preferredWidth':150,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(REFLECTION_COUNT.getDescription()) + "'},")
    113  - .append("{'id':" + ORIGIN + ",'name':'origin','defaultVisibleName':'Origin header','visibleName':'Origin header','preferredWidth':150,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(ORIGIN.getDescription()) + "'},")
    114  - .append("{'id':" + MIME_TYPE + ",'name':'MimeType','defaultVisibleName':'MIME type','visibleName':'MIME type','preferredWidth':100,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(MIME_TYPE.getDescription()) + "'},")
    115  - .append("{'id':" + NEW_COOKIES + ",'name':'NewCookies','defaultVisibleName':'New Cookies','visibleName':'New Cookies','preferredWidth':125,'readonly':true,'order':" + colOrder++ + ",'visible':true,'description':'" + StringEscapeUtils.escapeJson(NEW_COOKIES.getDescription()) + "'},")
    116  - .append("{'id':" + REQUEST_TIME + ",'name':'RequestTime','defaultVisibleName':'Request Time','visibleName':'Request Time','preferredWidth':150,'readonly':true,'order':" + colOrder++ + ",'visible':true,'description':'" + StringEscapeUtils.escapeJson(REQUEST_TIME.getDescription()) + "'},")
    117  - .append("{'id':" + RESPONSE_TIME + ",'name':'ResponseTime','defaultVisibleName':'Response Time','visibleName':'Response Time','preferredWidth':150,'readonly':true,'order':" + colOrder++ + ",'visible':true,'description':'" + StringEscapeUtils.escapeJson(RESPONSE_TIME.getDescription()) + "'},")
    118  - .append("{'id':" + RESPONSE_HASH + ",'name':'ResponseHash','defaultVisibleName':'Response Hash','visibleName':'Response Hash','preferredWidth':150,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(RESPONSE_HASH.getDescription()) + "'},")
    119  - .append("{'id':" + RTT + ",'name':'RTT','defaultVisibleName':'RTT (ms)','visibleName':'RTT (ms)','preferredWidth':100,'readonly':true,'order':" + colOrder++ + ",'visible':true,'description':'" + StringEscapeUtils.escapeJson(RTT.getDescription()) + "'},")
    120  - .append("{'id':" + LISTENER_INTERFACE + ",'name':'ListenerInterface','defaultVisibleName':'Proxy Listener Interface','visibleName':'Proxy Listener Interface','preferredWidth':150,'readonly':true,'order':" + colOrder++ + ",'visible':true,'description':'" + StringEscapeUtils.escapeJson(LISTENER_INTERFACE.getDescription()) + "'},")
    121  - .append("{'id':" + CLIENT_IP + ",'name':'ClientIP','defaultVisibleName':'Proxy Client IP','visibleName':'Proxy Client IP','preferredWidth':150,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(CLIENT_IP.getDescription()) + "'},")
    122  - .append("{'id':" + RESPONSE_CONTENT_TYPE + ",'name':'ResponseContentType','defaultVisibleName':'Response Content-Type','visibleName':'Response Content-Type','preferredWidth':150,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(RESPONSE_CONTENT_TYPE.getDescription()) + "'},")
    123  - .append("{'id':" + HASGETPARAM + ",'name':'HasQueryStringParam','defaultVisibleName':'Query String?','visibleName':'Query String?','preferredWidth':50,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(HASGETPARAM.getDescription()) + "'},")
    124  - .append("{'id':" + HASPOSTPARAM + ",'name':'HasBodyParam','defaultVisibleName':'Body Params?','visibleName':'Body Params?','preferredWidth':50,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(HASPOSTPARAM.getDescription()) + "'},")
    125  - .append("{'id':" + HASCOOKIEPARAM + ",'name':'HasCookieParam','defaultVisibleName':'Sent Cookie?','visibleName':'Sent Cookie?','preferredWidth':50,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(HASCOOKIEPARAM.getDescription()) + "'},")
    126  - .append("{'id':" + SENTCOOKIES + ",'name':'SentCookies','defaultVisibleName':'Sent Cookies','visibleName':'Sent Cookies','preferredWidth':150,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(SENTCOOKIES.getDescription()) + "'},")
    127  - .append("{'id':" + USES_COOKIE_JAR + ",'name':'UsesCookieJar','defaultVisibleName':'Contains cookie jar?','visibleName':'Contains cookie jar?','preferredWidth':150,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(USES_COOKIE_JAR.getDescription()) + "'},")
    128  - .append("{'id':" + REQUEST_CONTENT_TYPE + ",'name':'RequestContentType','defaultVisibleName':'Request Content Type','visibleName':'Request Type','preferredWidth':150,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(REQUEST_CONTENT_TYPE.getDescription()) + "'},")
    129  - .append("{'id':" + REFERRER + ",'name':'Referrer','defaultVisibleName':'Referrer','visibleName':'Referrer','preferredWidth':250,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(REFERRER.getDescription()) + "'},")
    130  - .append("{'id':" + REDIRECT_URL + ",'name':'Redirect','defaultVisibleName':'Redirect','visibleName':'Redirect','preferredWidth':250,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(REDIRECT_URL.getDescription()) + "'},")
    131  - .append("{'id':" + HAS_SET_COOKIES + ",'name':'HasSetCookies','defaultVisibleName':'Set-Cookie?','visibleName':'Set-Cookie?','preferredWidth':50,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(HAS_SET_COOKIES.getDescription()) + "'},")
    132  - .append("{'id':" + REQUEST_BODY + ",'name':'Request','defaultVisibleName':'Request Body','visibleName':'Request Body','preferredWidth':150,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(REQUEST_BODY.getDescription()) + "'},")
    133  - .append("{'id':" + REQUEST_HEADERS + ",'name':'RequestHeaders','defaultVisibleName':'Request Headers','visibleName':'Request Headers','preferredWidth':150,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(REQUEST_HEADERS.getDescription()) + "'},")
    134  - .append("{'id':" + RESPONSE_BODY + ",'name':'Response','defaultVisibleName':'Response Body','visibleName':'Response Body','preferredWidth':150,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(RESPONSE_BODY.getDescription()) + "'},")
    135  - .append("{'id':" + RESPONSE_HEADERS + ",'name':'ResponseHeaders','defaultVisibleName':'Response Headers','visibleName':'Response Headers','preferredWidth':150,'readonly':true,'order':" + colOrder++ + ",'visible':false,'description':'" + StringEscapeUtils.escapeJson(RESPONSE_HEADERS.getDescription()) + "'}")
     90 + .append("{\"id\":" + NUMBER + ",\"name\":\"Number\",\"defaultVisibleName\":\"#\",\"visibleName\":\"#\",\"preferredWidth\":65,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":true,\"description\":\"" + StringEscapeUtils.escapeJson(NUMBER.getDescription()) + "\"},")
     91 + .append("{\"id\":" + TAGS + ",\"name\":\"Tags\",\"defaultVisibleName\":\"Tags\",\"visibleName\":\"Tags\",\"preferredWidth\":100,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":true,\"description\":\"" + StringEscapeUtils.escapeJson(TAGS.getDescription()) + "\"},")
     92 + .append("{\"id\":" + COMPLETE + ",\"name\":\"Complete\",\"defaultVisibleName\":\"Complete\",\"visibleName\":\"Complete\",\"preferredWidth\":80,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":true,\"description\":\"" + StringEscapeUtils.escapeJson(COMPLETE.getDescription()) + "\"},")
     93 + .append("{\"id\":" + PROXY_TOOL + ",\"name\":\"Tool\",\"defaultVisibleName\":\"Tool\",\"visibleName\":\"Tool\",\"preferredWidth\":70,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":true,\"description\":\"" + StringEscapeUtils.escapeJson(PROXY_TOOL.getDescription()) + "\"},")
     94 + .append("{\"id\":" + ISSSL + ",\"name\":\"IsSSL\",\"defaultVisibleName\":\"SSL\",\"visibleName\":\"SSL\",\"preferredWidth\":50,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(ISSSL.getDescription()) + "\"},")
     95 + .append("{\"id\":" + METHOD + ",\"name\":\"Method\",\"defaultVisibleName\":\"Method\",\"visibleName\":\"Method\",\"preferredWidth\":65,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":true,\"description\":\"" + StringEscapeUtils.escapeJson(METHOD.getDescription()) + "\"},")
     96 + .append("{\"id\":" + PROTOCOL + ",\"name\":\"Protocol\",\"defaultVisibleName\":\"Protocol\",\"visibleName\":\"Protocol\",\"preferredWidth\":80,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(PROTOCOL.getDescription()) + "\"},")
     97 + .append("{\"id\":" + HOSTNAME + ",\"name\":\"Hostname\",\"defaultVisibleName\":\"Host Name\",\"visibleName\":\"Host Name\",\"preferredWidth\":150,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(HOSTNAME.getDescription()) + "\"},")
     98 + .append("{\"id\":" + PORT + ",\"name\":\"TargetPort\",\"defaultVisibleName\":\"Port\",\"visibleName\":\"Port\",\"preferredWidth\":50,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(PORT.getDescription()) + "\"},")
     99 + .append("{\"id\":" + HOST + ",\"name\":\"Host\",\"defaultVisibleName\":\"Host\",\"visibleName\":\"Host\",\"preferredWidth\":150,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":true,\"description\":\"" + StringEscapeUtils.escapeJson(HOST.getDescription()) + "\"},")
     100 + .append("{\"id\":" + PATH + ",\"name\":\"Path\",\"defaultVisibleName\":\"Path\",\"visibleName\":\"Path\",\"preferredWidth\":250,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":true,\"description\":\"" + StringEscapeUtils.escapeJson(PATH.getDescription()) + "\"},")
     101 + .append("{\"id\":" + EXTENSION + ",\"name\":\"UrlExtension\",\"defaultVisibleName\":\"Extension\",\"visibleName\":\"Extension\",\"preferredWidth\":70,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(EXTENSION.getDescription()) + "\"},")
     102 + .append("{\"id\":" + QUERY + ",\"name\":\"Query\",\"defaultVisibleName\":\"Query\",\"visibleName\":\"Query\",\"preferredWidth\":250,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":true,\"description\":\"" + StringEscapeUtils.escapeJson(QUERY.getDescription()) + "\"},")
     103 + .append("{\"id\":" + PATHQUERY + ",\"name\":\"Path Query\",\"defaultVisibleName\":\"Path Query\",\"visibleName\":\"Path Query\",\"preferredWidth\":250,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(PATHQUERY.getDescription()) + "\"},")
     104 + .append("{\"id\":" + URL + ",\"name\":\"Url\",\"defaultVisibleName\":\"URL\",\"visibleName\":\"URL\",\"preferredWidth\":250,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(URL.getDescription()) + "\"},")
     105 + .append("{\"id\":" + HASPARAMS + ",\"name\":\"Has Params\",\"defaultVisibleName\":\"Has Params\",\"visibleName\":\"Has Params\",\"preferredWidth\":75,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(HASPARAMS.getDescription()) + "\"},")
     106 + .append("{\"id\":" + STATUS + ",\"name\":\"Status\",\"defaultVisibleName\":\"Status\",\"visibleName\":\"Status\",\"preferredWidth\":55,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":true,\"description\":\"" + StringEscapeUtils.escapeJson(STATUS.getDescription()) + "\"},")
     107 + .append("{\"id\":" + TITLE + ",\"name\":\"Title\",\"defaultVisibleName\":\"Title\",\"visibleName\":\"Title\",\"preferredWidth\":100,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":true,\"description\":\"" + StringEscapeUtils.escapeJson(TITLE.getDescription()) + "\"},")
     108 + .append("{\"id\":" + REQUEST_LENGTH + ",\"name\":\"RequestLength\",\"defaultVisibleName\":\"Request Length\",\"visibleName\":\"Request Length\",\"preferredWidth\":150,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(REQUEST_LENGTH.getDescription()) + "\"},")
     109 + .append("{\"id\":" + RESPONSE_LENGTH + ",\"name\":\"ResponseLength\",\"defaultVisibleName\":\"Response Length\",\"visibleName\":\"Response Length\",\"preferredWidth\":125,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":true,\"description\":\"" + StringEscapeUtils.escapeJson(RESPONSE_LENGTH.getDescription()) + "\"},")
     110 + .append("{\"id\":" + INFERRED_TYPE + ",\"name\":\"InferredType\",\"defaultVisibleName\":\"Inferred Type\",\"visibleName\":\"Inferred Type\",\"preferredWidth\":100,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":true,\"description\":\"" + StringEscapeUtils.escapeJson(INFERRED_TYPE.getDescription()) + "\"},")
     111 + .append("{\"id\":" + COMMENT + ",\"name\":\"Comment\",\"defaultVisibleName\":\"Comment\",\"visibleName\":\"Comment\",\"preferredWidth\":200,\"readonly\":false,\"order\":" + colOrder++ + ",\"visible\":true,\"description\":\"" + StringEscapeUtils.escapeJson(COMMENT.getDescription()) + "\"},")
     112 + .append("{\"id\":" + PARAMETER_COUNT + ",\"name\":\"ParameterCount\",\"defaultVisibleName\":\"Parameter Count\",\"visibleName\":\"Parameter Count\",\"preferredWidth\":150,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":true,\"description\":\"" + StringEscapeUtils.escapeJson(PARAMETER_COUNT.getDescription()) + "\"},")
     113 + .append("{\"id\":" + PARAMETERS + ",\"name\":\"Parameters\",\"defaultVisibleName\":\"Parameters\",\"visibleName\":\"Parameters\",\"preferredWidth\":150,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(PARAMETERS.getDescription()) + "\"},")
     114 + .append("{\"id\":" + REFLECTED_PARAMS + ",\"name\":\"ReflectedParams\",\"defaultVisibleName\":\"Reflected Params\",\"visibleName\":\"Reflected Params\",\"preferredWidth\":150,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":true,\"description\":\"" + StringEscapeUtils.escapeJson(REFLECTED_PARAMS.getDescription()) + "\"},")
     115 + .append("{\"id\":" + REFLECTION_COUNT + ",\"name\":\"ReflectionCount\",\"defaultVisibleName\":\"Reflection Count\",\"visibleName\":\"Reflection Count\",\"preferredWidth\":150,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(REFLECTION_COUNT.getDescription()) + "\"},")
     116 + .append("{\"id\":" + ORIGIN + ",\"name\":\"origin\",\"defaultVisibleName\":\"Origin header\",\"visibleName\":\"Origin header\",\"preferredWidth\":150,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(ORIGIN.getDescription()) + "\"},")
     117 + .append("{\"id\":" + MIME_TYPE + ",\"name\":\"MimeType\",\"defaultVisibleName\":\"MIME type\",\"visibleName\":\"MIME type\",\"preferredWidth\":100,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(MIME_TYPE.getDescription()) + "\"},")
     118 + .append("{\"id\":" + NEW_COOKIES + ",\"name\":\"NewCookies\",\"defaultVisibleName\":\"New Cookies\",\"visibleName\":\"New Cookies\",\"preferredWidth\":125,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":true,\"description\":\"" + StringEscapeUtils.escapeJson(NEW_COOKIES.getDescription()) + "\"},")
     119 + .append("{\"id\":" + REQUEST_TIME + ",\"name\":\"RequestTime\",\"defaultVisibleName\":\"Request Time\",\"visibleName\":\"Request Time\",\"preferredWidth\":150,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":true,\"description\":\"" + StringEscapeUtils.escapeJson(REQUEST_TIME.getDescription()) + "\"},")
     120 + .append("{\"id\":" + RESPONSE_TIME + ",\"name\":\"ResponseTime\",\"defaultVisibleName\":\"Response Time\",\"visibleName\":\"Response Time\",\"preferredWidth\":150,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":true,\"description\":\"" + StringEscapeUtils.escapeJson(RESPONSE_TIME.getDescription()) + "\"},")
     121 + .append("{\"id\":" + RESPONSE_HASH + ",\"name\":\"ResponseHash\",\"defaultVisibleName\":\"Response Hash\",\"visibleName\":\"Response Hash\",\"preferredWidth\":150,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(RESPONSE_HASH.getDescription()) + "\"},")
     122 + .append("{\"id\":" + RTT + ",\"name\":\"RTT\",\"defaultVisibleName\":\"RTT (ms)\",\"visibleName\":\"RTT (ms)\",\"preferredWidth\":100,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":true,\"description\":\"" + StringEscapeUtils.escapeJson(RTT.getDescription()) + "\"},")
     123 + .append("{\"id\":" + LISTENER_INTERFACE + ",\"name\":\"ListenerInterface\",\"defaultVisibleName\":\"Proxy Listener Interface\",\"visibleName\":\"Proxy Listener Interface\",\"preferredWidth\":150,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":true,\"description\":\"" + StringEscapeUtils.escapeJson(LISTENER_INTERFACE.getDescription()) + "\"},")
     124 + .append("{\"id\":" + CLIENT_IP + ",\"name\":\"ClientIP\",\"defaultVisibleName\":\"Proxy Client IP\",\"visibleName\":\"Proxy Client IP\",\"preferredWidth\":150,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(CLIENT_IP.getDescription()) + "\"},")
     125 + .append("{\"id\":" + RESPONSE_CONTENT_TYPE + ",\"name\":\"ResponseContentType\",\"defaultVisibleName\":\"Response Content-Type\",\"visibleName\":\"Response Content-Type\",\"preferredWidth\":150,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(RESPONSE_CONTENT_TYPE.getDescription()) + "\"},")
     126 + .append("{\"id\":" + HASGETPARAM + ",\"name\":\"HasQueryStringParam\",\"defaultVisibleName\":\"Query String?\",\"visibleName\":\"Query String?\",\"preferredWidth\":50,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(HASGETPARAM.getDescription()) + "\"},")
     127 + .append("{\"id\":" + HASPOSTPARAM + ",\"name\":\"HasBodyParam\",\"defaultVisibleName\":\"Body Params?\",\"visibleName\":\"Body Params?\",\"preferredWidth\":50,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(HASPOSTPARAM.getDescription()) + "\"},")
     128 + .append("{\"id\":" + HASCOOKIEPARAM + ",\"name\":\"HasCookieParam\",\"defaultVisibleName\":\"Sent Cookie?\",\"visibleName\":\"Sent Cookie?\",\"preferredWidth\":50,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(HASCOOKIEPARAM.getDescription()) + "\"},")
     129 + .append("{\"id\":" + SENTCOOKIES + ",\"name\":\"SentCookies\",\"defaultVisibleName\":\"Sent Cookies\",\"visibleName\":\"Sent Cookies\",\"preferredWidth\":150,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(SENTCOOKIES.getDescription()) + "\"},")
     130 + .append("{\"id\":" + USES_COOKIE_JAR + ",\"name\":\"UsesCookieJar\",\"defaultVisibleName\":\"Contains cookie jar?\",\"visibleName\":\"Contains cookie jar?\",\"preferredWidth\":150,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(USES_COOKIE_JAR.getDescription()) + "\"},")
     131 + .append("{\"id\":" + REQUEST_CONTENT_TYPE + ",\"name\":\"RequestContentType\",\"defaultVisibleName\":\"Request Content Type\",\"visibleName\":\"Request Type\",\"preferredWidth\":150,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(REQUEST_CONTENT_TYPE.getDescription()) + "\"},")
     132 + .append("{\"id\":" + REFERRER + ",\"name\":\"Referrer\",\"defaultVisibleName\":\"Referrer\",\"visibleName\":\"Referrer\",\"preferredWidth\":250,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(REFERRER.getDescription()) + "\"},")
     133 + .append("{\"id\":" + REDIRECT_URL + ",\"name\":\"Redirect\",\"defaultVisibleName\":\"Redirect\",\"visibleName\":\"Redirect\",\"preferredWidth\":250,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(REDIRECT_URL.getDescription()) + "\"},")
     134 + .append("{\"id\":" + HAS_SET_COOKIES + ",\"name\":\"HasSetCookies\",\"defaultVisibleName\":\"Set-Cookie?\",\"visibleName\":\"Set-Cookie?\",\"preferredWidth\":50,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(HAS_SET_COOKIES.getDescription()) + "\"},")
     135 + .append("{\"id\":" + REQUEST_BODY + ",\"name\":\"Request\",\"defaultVisibleName\":\"Request Body\",\"visibleName\":\"Request Body\",\"preferredWidth\":150,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(REQUEST_BODY.getDescription()) + "\"},")
     136 + .append("{\"id\":" + REQUEST_BODY_LENGTH + ",\"name\":\"RequestBodyLength\",\"defaultVisibleName\":\"Request Body Length\",\"visibleName\":\"Request Body Length\",\"preferredWidth\":150,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(REQUEST_BODY_LENGTH.getDescription()) + "\"},")
     137 + .append("{\"id\":" + REQUEST_HEADERS + ",\"name\":\"RequestHeaders\",\"defaultVisibleName\":\"Request Headers\",\"visibleName\":\"Request Headers\",\"preferredWidth\":150,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(REQUEST_HEADERS.getDescription()) + "\"},")
     138 + .append("{\"id\":" + RESPONSE_BODY + ",\"name\":\"Response\",\"defaultVisibleName\":\"Response Body\",\"visibleName\":\"Response Body\",\"preferredWidth\":150,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(RESPONSE_BODY.getDescription()) + "\"},")
     139 + .append("{\"id\":" + RESPONSE_BODY_LENGTH + ",\"name\":\"ResponseBodyLength\",\"defaultVisibleName\":\"Response Body Length\",\"visibleName\":\"Response Body Length\",\"preferredWidth\":150,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(RESPONSE_BODY_LENGTH.getDescription()) + "\"},")
     140 + .append("{\"id\":" + RESPONSE_HEADERS + ",\"name\":\"ResponseHeaders\",\"defaultVisibleName\":\"Response Headers\",\"visibleName\":\"Response Headers\",\"preferredWidth\":150,\"readonly\":true,\"order\":" + colOrder++ + ",\"visible\":false,\"description\":\"" + StringEscapeUtils.escapeJson(RESPONSE_HEADERS.getDescription()) + "\"}")
    136 141   .append("]").toString();
    137 142   
    138 143   
    skipped 4 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/util/MoreHelp.java
    skipped 109 lines
    110 110   
    111 111   // public static void checkForUpdate(boolean showMessages) {
    112 112   // new Thread(() -> {
    113  - // IExtensionHelpers helper = LoggerPlusPlus.callbacks.getHelpers();
     113 + // IExtensionHelpers helper = LoggerPlusPlus.montoya.getHelpers();
    114 114   // Double currenVersion = Globals.VERSION;
    115 115   // Double latestVersion = 0.0;
    116 116   // int updateStatus = -1;
    skipped 3 lines
    120 120   // URL changeLogURL = new URL(Globals.CHANGELOG);
    121 121   // byte[] request = helper.buildHttpRequest(changeLogURL);
    122 122   // byte[] response =
    123  - // LoggerPlusPlus.callbacks.makeHttpRequest(changeLogURL.getHost(), 443, true,
     123 + // LoggerPlusPlus.montoya.makeHttpRequest(changeLogURL.getHost(), 443, true,
    124 124   // request);
    125 125   //
    126 126   // if (response != null) {
    skipped 21 lines
    148 148   //
    149 149   // }
    150 150   // } catch (Exception e) {
    151  - // LoggerPlusPlus.callbacks.printError(e.getMessage());
     151 + // LoggerPlusPlus.montoya.printError(e.getMessage());
    152 152   // }
    153 153   //
    154 154   // switch (updateStatus) {
    155 155   // case -1:
    156 156   // updateMessage = "Check for update failed: Could not get a proper response
    157 157   // from " + Globals.CHANGELOG;
    158  - // LoggerPlusPlus.callbacks.printError(updateMessage);
     158 + // LoggerPlusPlus.montoya.printError(updateMessage);
    159 159   // break;
    160 160   // case 0:
    161 161   // updateMessage = "This version is up to date.";
    162  - // LoggerPlusPlus.callbacks.printOutput(updateMessage);
     162 + // LoggerPlusPlus.montoya.printOutput(updateMessage);
    163 163   // break;
    164 164   // case 1:
    165 165   // updateMessage = "Version " + latestVersion.toString() + " is available via
    166 166   // GitHub. Visit the extension homepage.";
    167  - // if (LoggerPlusPlus.callbacks.isExtensionBapp()) {
     167 + // if (LoggerPlusPlus.montoya.isExtensionBapp()) {
    168 168   // updateMessage += "\nAs you are using BApp Store, you have to remove it first
    169 169   // and download the Jar file from the GitHub repository. ";
    170 170   // } else {
    171  - // if (LoggerPlusPlus.callbacks.getExtensionFilename() != null) {
     171 + // if (LoggerPlusPlus.montoya.getExtensionFilename() != null) {
    172 172   // int res = MoreHelp.askConfirmMessage("Update Available", "An update is
    173 173   // available. Would you like to update now?", new String[]{"Yes", "No"});
    174 174   // if (res == JOptionPane.OK_OPTION) {
    skipped 1 lines
    176 176   // //TODO FIXME
    177 177   // URL updateUrl = new URL(Globals.UPDATE_URL);
    178 178   // InputStream input = updateUrl.openStream();
    179  - // Path outputPath = Paths.get(LoggerPlusPlus.callbacks.getExtensionFilename());
     179 + // Path outputPath = Paths.get(LoggerPlusPlus.montoya.getExtensionFilename());
    180 180   // Files.copy(input, outputPath, StandardCopyOption.REPLACE_EXISTING);
    181 181   // } catch (Exception e) {
    182 182   // MoreHelp.showMessage("Could not update the plugin. Please visit the extension
    skipped 2 lines
    185 185   // }
    186 186   // MoreHelp.showMessage("Update complete. Re-enable the plugin in the extensions
    187 187   // tab to continue.");
    188  - // LoggerPlusPlus.callbacks.unloadExtension();
     188 + // LoggerPlusPlus.montoya.unloadExtension();
    189 189   // return;
    190 190   // }
    191 191   // }
    192 192   // }
    193  - // LoggerPlusPlus.callbacks.printOutput(updateMessage);
     193 + // LoggerPlusPlus.montoya.printOutput(updateMessage);
    194 194   // break;
    195 195   // case 2:
    196 196   // updateMessage = "This version is more up to date than the GitHub version! Are
    197 197   // you a time traveler? or just a keen ninja? ;)";
    198  - // LoggerPlusPlus.callbacks.printOutput(updateMessage);
     198 + // LoggerPlusPlus.montoya.printOutput(updateMessage);
    199 199   // break;
    200 200   // }
    201 201   // if (!showMessages) return;
    skipped 61 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/util/userinterface/dialog/ColorFilterDialog.java
    1 1  package com.nccgroup.loggerplusplus.util.userinterface.dialog;
    2 2   
    3  -import com.nccgroup.loggerplusplus.filter.colorfilter.ColorFilter;
     3 +import com.nccgroup.loggerplusplus.filter.colorfilter.TableColorRule;
    4 4  import com.nccgroup.loggerplusplus.filterlibrary.FilterLibraryController;
    5 5   
    6 6  import javax.swing.*;
    skipped 71 lines
    78 78   btnAddFilter.addActionListener(new ActionListener() {
    79 79   @Override
    80 80   public void actionPerformed(ActionEvent actionEvent) {
    81  - ((ColorFilterTableModel) filterTable.getModel()).addFilter(new ColorFilter());
     81 + ((ColorFilterTableModel) filterTable.getModel()).addFilter(new TableColorRule());
    82 82   }
    83 83   });
    84 84   JButton btnClose = new JButton("Close");
    skipped 15 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/util/userinterface/dialog/ColorFilterTable.java
    1 1  package com.nccgroup.loggerplusplus.util.userinterface.dialog;
    2 2   
    3  -import com.nccgroup.loggerplusplus.filter.colorfilter.ColorFilter;
     3 +import com.nccgroup.loggerplusplus.filter.colorfilter.TableColorRule;
    4 4  import com.nccgroup.loggerplusplus.filterlibrary.FilterLibraryController;
    5 5  import com.nccgroup.loggerplusplus.util.userinterface.renderer.ButtonRenderer;
    6 6  import com.nccgroup.loggerplusplus.util.userinterface.renderer.ColorRenderer;
    skipped 60 lines
    67 67   if(this.getSelectedRow() > 0){
    68 68   ((ColorFilterTableModel) this.getModel()).switchRows(this.getSelectedRow(), this.getSelectedRow()-1);
    69 69   this.getSelectionModel().setSelectionInterval(this.getSelectedRow()-1, this.getSelectedRow()-1);
    70  - ColorFilter filter = ((ColorFilterTableModel) this.getModel()).getFilterAtRow(this.getSelectedRow());
     70 + TableColorRule filter = ((ColorFilterTableModel) this.getModel()).getFilterAtRow(this.getSelectedRow());
    71 71   filterLibraryController.updateColorFilter(filter);
    72 72   }
    73 73   }
    skipped 1 lines
    75 75   if(this.getSelectedRow() >= 0 && this.getSelectedRow() < this.getRowCount()){
    76 76   ((ColorFilterTableModel) this.getModel()).switchRows(this.getSelectedRow(), this.getSelectedRow()+1);
    77 77   this.getSelectionModel().setSelectionInterval(this.getSelectedRow()+1, this.getSelectedRow()+1);
    78  - ColorFilter filter = ((ColorFilterTableModel) this.getModel()).getFilterAtRow(this.getSelectedRow());
     78 + TableColorRule filter = ((ColorFilterTableModel) this.getModel()).getFilterAtRow(this.getSelectedRow());
    79 79   filterLibraryController.updateColorFilter(filter);
    80 80   }
    81 81   }
    skipped 2 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/util/userinterface/dialog/ColorFilterTableModel.java
    1 1  package com.nccgroup.loggerplusplus.util.userinterface.dialog;
    2 2   
    3 3  import com.nccgroup.loggerplusplus.LoggerPlusPlus;
    4  -import com.nccgroup.loggerplusplus.filter.colorfilter.ColorFilter;
    5  -import com.nccgroup.loggerplusplus.filter.logfilter.LogFilter;
     4 +import com.nccgroup.loggerplusplus.filter.colorfilter.TableColorRule;
     5 +import com.nccgroup.loggerplusplus.filter.logfilter.LogTableFilter;
    6 6  import com.nccgroup.loggerplusplus.filter.parser.ParseException;
    7 7  import com.nccgroup.loggerplusplus.filterlibrary.FilterLibraryController;
    8 8   
    skipped 9 lines
    18 18  public class ColorFilterTableModel extends AbstractTableModel {
    19 19   
    20 20   private final Map<Short, UUID> rowUUIDs = new HashMap<Short, UUID>();
    21  - private final Map<UUID, ColorFilter> filters;
     21 + private final Map<UUID, TableColorRule> filters;
    22 22   private final String[] columnNames = {"Title", "LogFilter", "Foreground Color", "Background Color", "Enabled", ""};
    23 23   private final JButton removeButton = new JButton("Remove");
    24 24   private final FilterLibraryController filterLibraryController;
    skipped 2 lines
    27 27   this.filterLibraryController = filterLibraryController;
    28 28   //Sort existing filters by their priority before adding to table.
    29 29   filters = filterLibraryController.getColorFilters();
    30  - List<ColorFilter> sorted = new ArrayList<ColorFilter>(filters.values());
     30 + List<TableColorRule> sorted = new ArrayList<TableColorRule>(filters.values());
    31 31   Collections.sort(sorted);
    32  - for (ColorFilter filter : sorted) {
    33  - rowUUIDs.put((short) rowUUIDs.size(), filter.getUUID());
     32 + for (TableColorRule filter : sorted) {
     33 + rowUUIDs.put((short) rowUUIDs.size(), filter.getUuid());
    34 34   }
    35 35   }
    36 36   
    skipped 34 lines
    71 71   }
    72 72   
    73 73   public boolean validFilterAtRow(int row) {
    74  - return getFilterAtRow(row).getFilter() != null;
     74 + return getFilterAtRow(row).getFilterExpression() != null;
    75 75   }
    76 76   
    77 77  // public LogFilter getFilterAtRow(int row){
    78 78  // return filters.get(rowUUIDs.get((short) row)).getFilter();
    79 79  // }
    80 80   
    81  - public ColorFilter getFilterAtRow(int row){
     81 + public TableColorRule getFilterAtRow(int row){
    82 82   return filters.get(rowUUIDs.get((short) row));
    83 83   }
    84 84   
    85 85   public void setValueAt(Object value, int row, int col) {
    86 86   UUID rowUid = rowUUIDs.get((short) row);
    87  - ColorFilter filter = filters.get(rowUid);
     87 + TableColorRule filter = filters.get(rowUid);
    88 88   switch (col) {
    89 89   case 0:
    90 90   filter.setName((String) value);
    91 91   break;
    92 92   case 1: {
    93  - filter.setFilterString((String) value);
    94  - try {
    95  - filter.setFilter(new LogFilter(LoggerPlusPlus.instance.getLibraryController(), (String) value));
    96  - } catch (ParseException e) {
    97  - filter.setFilter(null);
    98  - }
     93 + filter.trySetFilter((String) value);
    99 94   break;
    100 95   }
    101 96   case 2:
    skipped 32 lines
    134 129   return col != 5;
    135 130   }
    136 131   
    137  - public void addFilter(ColorFilter filter){
     132 + public void addFilter(TableColorRule filter){
    138 133   int i = filters.size();
    139 134   filterLibraryController.addColorFilter(filter);
    140  - rowUUIDs.put((short) i, filter.getUUID());
     135 + rowUUIDs.put((short) i, filter.getUuid());
    141 136   filter.setPriority((short) i);
    142 137   this.fireTableRowsInserted(i, i);
    143 138   }
    skipped 1 lines
    145 140   public void onClick(int row, int column) {
    146 141   if(row != -1 && row < filters.size() && column == 5) {
    147 142   synchronized (rowUUIDs) {
    148  - ColorFilter removedFilter = filters.get(rowUUIDs.get((short) row));
     143 + TableColorRule removedFilter = filters.get(rowUUIDs.get((short) row));
    149 144   filterLibraryController.removeColorFilter(removedFilter);
    150 145   this.fireTableRowsDeleted(row, row);
    151 146   rowUUIDs.remove((short) row);
    skipped 11 lines
    163 158   UUID toUid = this.rowUUIDs.get((short) to);
    164 159   rowUUIDs.put((short) to, rowUUIDs.get((short) from));
    165 160   rowUUIDs.put((short) from, toUid);
    166  - ColorFilter toFilter = filters.get(rowUUIDs.get((short) to));
     161 + TableColorRule toFilter = filters.get(rowUUIDs.get((short) to));
    167 162   toFilter.setPriority((short) to);
    168  - ColorFilter fromFilter = filters.get(rowUUIDs.get((short) from));
     163 + TableColorRule fromFilter = filters.get(rowUUIDs.get((short) from));
    169 164   fromFilter.setPriority((short) from);
    170 165   filterLibraryController.updateColorFilter(toFilter);
    171 166   filterLibraryController.updateColorFilter(fromFilter);
    skipped 2 lines
    174 169   }
    175 170   
    176 171   public void removeAll() {
    177  - for (ColorFilter filter : new ArrayList<>(filterLibraryController.getColorFilters().values())) {
     172 + for (TableColorRule filter : new ArrayList<>(filterLibraryController.getColorFilters().values())) {
    178 173   filterLibraryController.removeColorFilter(filter);
    179 174   }
    180 175   
    skipped 5 lines
  • ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/util/userinterface/dialog/TagTable.java
    skipped 1 lines
    2 2   
    3 3  import com.nccgroup.loggerplusplus.filter.tag.Tag;
    4 4  import com.nccgroup.loggerplusplus.filterlibrary.FilterLibraryController;
     5 +import com.nccgroup.loggerplusplus.util.userinterface.ColorEditor;
    5 6  import com.nccgroup.loggerplusplus.util.userinterface.renderer.ButtonRenderer;
     7 +import com.nccgroup.loggerplusplus.util.userinterface.renderer.ColorRenderer;
    6 8  import com.nccgroup.loggerplusplus.util.userinterface.renderer.FilterRenderer;
    7 9   
    8 10  import javax.swing.*;
    skipped 19 lines
    28 30   ((JComponent) this.getDefaultRenderer(JButton.class)).setOpaque(true);
    29 31   
    30 32   this.getColumnModel().getColumn(1).setCellRenderer(new FilterRenderer());
    31  - this.getColumnModel().getColumn(3).setCellRenderer(new ButtonRenderer());
     33 + this.getColumnModel().getColumn(2).setCellRenderer(new ColorRenderer(true));
     34 + this.getColumnModel().getColumn(2).setCellEditor(new ColorEditor());
     35 + this.getColumnModel().getColumn(3).setCellRenderer(new ColorRenderer(true));
     36 + this.getColumnModel().getColumn(3).setCellEditor(new ColorEditor());
     37 + this.getColumnModel().getColumn(5).setCellRenderer(new ButtonRenderer());
    32 38   
    33 39   
    34 40   this.setDragEnabled(true);
    skipped 44 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/util/userinterface/dialog/TagTableModel.java
    1 1  package com.nccgroup.loggerplusplus.util.userinterface.dialog;
    2 2   
    3  -import com.nccgroup.loggerplusplus.filter.logfilter.LogFilter;
     3 +import com.nccgroup.loggerplusplus.filter.logfilter.LogTableFilter;
    4 4  import com.nccgroup.loggerplusplus.filter.parser.ParseException;
    5 5  import com.nccgroup.loggerplusplus.filter.tag.Tag;
    6 6  import com.nccgroup.loggerplusplus.filterlibrary.FilterLibraryController;
    7 7   
    8 8  import javax.swing.*;
    9 9  import javax.swing.table.AbstractTableModel;
     10 +import java.awt.*;
    10 11  import java.util.*;
     12 +import java.util.List;
    11 13   
    12 14  /**
    13 15   * Created by corey on 19/07/17.
    skipped 2 lines
    16 18   
    17 19   private final Map<Short, UUID> rowUUIDs = new HashMap<Short, UUID>();
    18 20   private final Map<UUID, Tag> tags;
    19  - private final String[] columnNames = {"Tag", "LogFilter", "Enabled", ""};
     21 + private final String[] columnNames = {"Tag", "LogFilter", "Foreground Color", "Background Color", "Enabled", ""};
    20 22   private final JButton removeButton = new JButton("Remove");
    21 23   private final FilterLibraryController filterLibraryController;
    22 24   
    skipped 4 lines
    27 29   List<Tag> sorted = new ArrayList<Tag>(tags.values());
    28 30   Collections.sort(sorted);
    29 31   for (Tag filter : sorted) {
    30  - rowUUIDs.put((short) rowUUIDs.size(), filter.getUUID());
     32 + rowUUIDs.put((short) rowUUIDs.size(), filter.getUuid());
    31 33   }
    32 34   }
    33 35   
    skipped 21 lines
    55 57   case 1:
    56 58   return (tags.get(rowUid).getFilterString() == null ? "" : tags.get(rowUid).getFilterString());
    57 59   case 2:
    58  - return tags.get(rowUid).isEnabled();
     60 + return (tags.get(rowUid).getForegroundColor() == null ? Color.BLACK : tags.get(rowUid).getForegroundColor());
    59 61   case 3:
     62 + return (tags.get(rowUid).getBackgroundColor() == null ? Color.WHITE : tags.get(rowUid).getBackgroundColor());
     63 + case 4:
     64 + return tags.get(rowUid).isEnabled();
     65 + case 5:
    60 66   return removeButton;
    61 67   default:
    62 68   return false;
    skipped 1 lines
    64 70   }
    65 71   
    66 72   public boolean validFilterAtRow(int row) {
    67  - return getTagAtRow(row).getFilter() != null;
     73 + return getTagAtRow(row).getFilterExpression() != null;
    68 74   }
    69 75   
    70 76  // public LogFilter getFilterAtRow(int row){
    skipped 12 lines
    83 89   tag.setName((String) value);
    84 90   break;
    85 91   case 1: {
    86  - tag.setFilterString((String) value);
    87  - try {
    88  - tag.setFilter(new LogFilter(filterLibraryController, (String) value));
    89  - } catch (ParseException e) {
    90  - tag.setFilter(null);
    91  - }
     92 + tag.trySetFilter((String) value);
    92 93   break;
    93 94   }
    94 95   case 2:
     96 + tag.setForegroundColor((Color) value);
     97 + break;
     98 + case 3:
     99 + tag.setBackgroundColor((Color) value);
     100 + break;
     101 + case 4:
    95 102   tag.setEnabled((Boolean) value);
    96 103   break;
    97 104   default:
    skipped 8 lines
    106 113   public Class<?> getColumnClass(int columnIndex) {
    107 114   switch (columnIndex) {
    108 115   case 2:
    109  - return Boolean.class;
    110 116   case 3:
     117 + return Color.class;
     118 + case 4:
     119 + return Boolean.class;
     120 + case 5:
    111 121   return JButton.class;
    112 122   default:
    113 123   return String.class;
    skipped 2 lines
    116 126   
    117 127   @Override
    118 128   public boolean isCellEditable(int row, int col) {
    119  - return col != 3;
     129 + return col != 5;
    120 130   }
    121 131   
    122 132   public void addTag(Tag tag) {
    123 133   int i = tags.size();
    124 134   filterLibraryController.addTag(tag);
    125  - rowUUIDs.put((short) i, tag.getUUID());
     135 + rowUUIDs.put((short) i, tag.getUuid());
    126 136   tag.setPriority((short) i);
    127 137   this.fireTableRowsInserted(i, i);
    128 138   }
    129 139   
    130 140   public void onClick(int row, int column) {
    131  - if (row != -1 && row < tags.size() && column == 3) {
     141 + if (row != -1 && row < tags.size() && column == 5) {
    132 142   synchronized (rowUUIDs) {
    133 143   Tag removedFilter = tags.get(rowUUIDs.get((short) row));
    134 144   filterLibraryController.removeTag(removedFilter);
    skipped 36 lines
  • ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/util/userinterface/renderer/FilterRenderer.java
    1 1  package com.nccgroup.loggerplusplus.util.userinterface.renderer;
    2 2   
    3  -import com.nccgroup.loggerplusplus.filter.logfilter.LogFilter;
     3 +import com.nccgroup.loggerplusplus.filter.FilterExpression;
     4 +import com.nccgroup.loggerplusplus.filter.logfilter.LogTableFilter;
    4 5  import com.nccgroup.loggerplusplus.util.userinterface.dialog.ColorFilterTable;
    5 6  import com.nccgroup.loggerplusplus.util.userinterface.dialog.ColorFilterTableModel;
    6 7  import com.nccgroup.loggerplusplus.util.userinterface.dialog.TagTable;
    skipped 17 lines
    24 25   } else if (table instanceof TagTable) {
    25 26   validFilter = ((TagTableModel) table.getModel()).validFilterAtRow(row);
    26 27   } else {
    27  - validFilter = (value instanceof LogFilter);
     28 + validFilter = (value instanceof FilterExpression);
    28 29   }
    29 30   
    30 31   if(validFilter){
    skipped 11 lines
  • ■ ■ ■ ■ ■ ■
    src/main/java/com/nccgroup/loggerplusplus/util/userinterface/renderer/TagRenderer.java
     1 +package com.nccgroup.loggerplusplus.util.userinterface.renderer;
     2 + 
     3 +import com.nccgroup.loggerplusplus.filter.tag.Tag;
     4 +import org.jdesktop.swingx.HorizontalLayout;
     5 + 
     6 +import javax.swing.*;
     7 +import javax.swing.table.TableCellRenderer;
     8 +import java.awt.*;
     9 +import java.util.ArrayList;
     10 +import java.util.Collection;
     11 +import java.util.Collections;
     12 +import java.util.Enumeration;
     13 + 
     14 +/**
     15 + * Created by corey on 22/08/17.
     16 + */
     17 +public class TagRenderer implements TableCellRenderer {
     18 + @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
     19 + JPanel tagWrapper = new JPanel();
     20 + tagWrapper.setLayout(new HorizontalLayout(2));
     21 + tagWrapper.setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
     22 + 
     23 + if(value instanceof Collection){
     24 + for (Object o : ((Collection<Tag>) value).toArray()) {
     25 + JButton c = new JButton(((Tag) o).getName());
     26 + c.putClientProperty("JButton.buttonType", "roundRect");
     27 + c.setMargin(new Insets(7,4,7,4));
     28 + c.setBackground(((Tag) o).getBackgroundColor());
     29 + c.setForeground(((Tag) o).getForegroundColor());
     30 + tagWrapper.add(c);
     31 + }
     32 + }
     33 + 
     34 + return tagWrapper;
     35 + }
     36 +}
     37 + 
  • ■ ■ ■ ■ ■ ■
    src/main/resources/log4j2.xml
     1 +<Configuration xmlns:xi="http://www.w3.org/2001/XInclude" packages="com.nccgroup" status="WARN">
     2 + <Appenders>
     3 + <BurpAppender name="BurpAppender" />
     4 + <Console name="Out">
     5 + <PatternLayout pattern="%m%n"/>
     6 + </Console>
     7 + </Appenders>
     8 + <Loggers>
     9 + <Root level="DEBUG">
     10 + <AppenderRef ref="BurpAppender" />
     11 +<!-- <AppenderRef ref="Out" />-->
     12 + </Root>
     13 + </Loggers>
     14 +</Configuration>
  • ■ ■ ■ ■ ■
    src/test/java/Test.java
     1 +import com.nccgroup.loggerplusplus.LoggerPlusPlus;
     2 + 
    1 3  import java.lang.reflect.Method;
     4 +import java.util.ArrayList;
     5 +import java.util.Arrays;
     6 +import java.util.List;
    2 7   
    3 8  public class Test {
    4 9   public static void main(String[] args) {
    5 10   try {
    6 11   Method main = Class.forName("burp.StartBurp").getMethod("main", String[].class);
    7  - main.invoke(null, (Object) args);
     12 + ArrayList<String> argList = new ArrayList<>(Arrays.stream(args).toList());
     13 + argList.add("--developer-extension-class-name=" + LoggerPlusPlus.class.getName());
     14 + main.invoke(null, (Object) argList.toArray(new String[]{}));
    8 15   }catch (Exception e){
    9 16   System.err.println("Cannot start burp. Check the burp jar is correctly included in the classpath.");
     17 + e.printStackTrace();
    10 18   }
    11 19   }
    12 20  }
    skipped 1 lines
Please wait...
Page is in error, reload to recover